Socket
Socket
Sign inDemoInstall

@textile/datastore-ttl

Package Overview
Dependencies
Maintainers
4
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@textile/datastore-ttl - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

7

dist/index.d.ts
/// <reference types="node" />
import { Datastore, Key, Batch, Query } from 'interface-datastore';
export { Duration } from './duration';
import { Duration } from './duration';
export { Duration };
export interface TTLDatastoreOptions {

@@ -26,3 +27,3 @@ /**

constructor(ttl: number, batch: Batch<Value>, ttlOn: TTLOnFunction, ttlOff: TTLOffFunction);
put(key: Key, value: Value, ttl?: number): void;
put(key: Key, value: Value): void;
delete(key: Key): void;

@@ -43,5 +44,5 @@ commit(): Promise<void>;

private meta;
readonly options: TTLDatastoreOptions;
private lock;
private interval;
readonly options: TTLDatastoreOptions;
/**

@@ -48,0 +49,0 @@ * TTLDatastore creates a new datastore that supports TTL expirations.

@@ -24,6 +24,6 @@ "use strict";

const lexicographic_integer_1 = require("lexicographic-integer");
const duration_1 = require("./duration");
exports.Duration = duration_1.Duration;
const ttlPrefix = new interface_datastore_1.Key('ttl');
const expPrefix = new interface_datastore_1.Key('exp');
var duration_1 = require("./duration");
exports.Duration = duration_1.Duration;
class TTLBatch {

@@ -38,3 +38,3 @@ constructor(ttl, batch, ttlOn, ttlOff) {

}
put(key, value, ttl) {
put(key, value) {
this.on.push(key);

@@ -75,7 +75,11 @@ return this.batch.put(key, value);

*/
constructor(store, meta = new datastore_core_1.NamespaceDatastore(store, ttlPrefix), options = { ttl: 0, frequency: 10000 }) {
constructor(store, meta = new datastore_core_1.NamespaceDatastore(store, ttlPrefix), options) {
var _a, _b;
this.store = store;
this.meta = meta;
this.options = options;
this.interval = 0;
this.options = {
frequency: ((_a = options) === null || _a === void 0 ? void 0 : _a.frequency) || duration_1.Duration.Second * 10,
ttl: ((_b = options) === null || _b === void 0 ? void 0 : _b.ttl) || 0,
};
this.lock = new async_rwlock_1.RWLock();

@@ -94,6 +98,7 @@ this.startTTL();

// @note: ttlPrefix is required 'hack' because NamespaceDatastore doesn't take this into account
// @fixme: Assuming ttlPrefix is not a good idea, we should extract the prefix from the meta store
const lte = ttlPrefix.child(expPrefix.child(new interface_datastore_1.Key(exp)));
const query = {
prefix: expPrefix.toString(),
filters: [item => item.key.toString() <= lte.toString()],
filters: [item => item.key.less(lte)],
};

@@ -124,2 +129,3 @@ const meta = this.meta.batch();

}
return;
});

@@ -126,0 +132,0 @@ }

@@ -11,6 +11,12 @@ "use strict";

};
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const interface_datastore_1 = require("interface-datastore");
const datastore_core_1 = require("datastore-core");
const index_1 = require("./index");

@@ -25,4 +31,3 @@ const sleep = (ms) => new Promise(r => setTimeout(r, ms));

setup() {
const store = new interface_datastore_1.MemoryDatastore();
return new index_1.TTLDatastore(store);
return new index_1.TTLDatastore(new interface_datastore_1.MemoryDatastore());
},

@@ -37,4 +42,3 @@ teardown() {

beforeEach(() => {
const store = new interface_datastore_1.MemoryDatastore();
ttl = new index_1.TTLDatastore(store, new datastore_core_1.NamespaceDatastore(store, new interface_datastore_1.Key('ttl')), { ttl: 100, frequency: 20 });
ttl = new index_1.TTLDatastore(new interface_datastore_1.MemoryDatastore(), undefined, { ttl: 100, frequency: 20 });
});

@@ -128,2 +132,43 @@ it('should have default options', () => {

}));
it('should correctly expire batched items', () => __awaiter(void 0, void 0, void 0, function* () {
var e_1, _a, e_2, _b;
const batch = ttl.batch(100);
batch.put(key.child(new interface_datastore_1.Key('1')), value);
batch.put(key.child(new interface_datastore_1.Key('2')), value);
batch.put(key.child(new interface_datastore_1.Key('3')), value);
yield batch.commit();
let list = [];
try {
for (var _c = __asyncValues(ttl.query({})), _d; _d = yield _c.next(), !_d.done;) {
const { key } = _d.value;
list.push(key);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) yield _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
chai_1.expect(list).to.have.length(3);
ttl.ttl(key.child(new interface_datastore_1.Key('3')), 300);
yield sleep(200);
list = [];
const it = ttl.query({ prefix: key.toString() });
try {
for (var it_1 = __asyncValues(it), it_1_1; it_1_1 = yield it_1.next(), !it_1_1.done;) {
const kv = it_1_1.value;
list.push(kv.key);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (it_1_1 && !it_1_1.done && (_b = it_1.return)) yield _b.call(it_1);
}
finally { if (e_2) throw e_2.error; }
}
chai_1.expect(list).to.have.length(1);
}));
});

@@ -130,0 +175,0 @@ });

{
"name": "@textile/datastore-ttl",
"version": "0.0.2",
"version": "0.0.3",
"description": "An implementation of the Datastore interface that supports a time-to-live for key-value pairs.",

@@ -5,0 +5,0 @@ "main": "dist/index",

@@ -54,3 +54,5 @@ # Time to Live Datastore _(datastore-ttl)_

```typescript
import { Buffer } from 'buffer'
import { MemoryDatastore, Key } from 'interface-datastore'
import { TTLDatastore } from '@textile/datastore-ttl'

@@ -62,6 +64,11 @@ // Use any compliant Datastore

await ttl.put(key, Buffer.from('bar'), 1000)
// Wait 900 milliseconds...
await ttl.ttl(key, 100) // Keep alive for another 100 milliseconds
// Wait 900 ms...
await sleep(900)
// Keep alive for another 100 ms from now
await ttl.ttl(key, 100)
await ttl.has(key) // true
// Wait 110 milliseconds
await ttl.expiration(key) // <unix-timestamp>
await ttl.get(key) // <Buffer>
// Wait 110 ms
await sleep(110)
await ttl.has(key) // false

@@ -68,0 +75,0 @@ ```

import { expect } from 'chai'
import { MemoryDatastore, Key } from 'interface-datastore'
import { NamespaceDatastore } from 'datastore-core'
import { TTLDatastore } from './index'

@@ -15,4 +14,3 @@

setup() {
const store = new MemoryDatastore()
return new TTLDatastore(store)
return new TTLDatastore(new MemoryDatastore())
},

@@ -27,4 +25,3 @@ teardown() {

beforeEach(() => {
const store = new MemoryDatastore()
ttl = new TTLDatastore(store, new NamespaceDatastore(store, new Key('ttl')), { ttl: 100, frequency: 20 })
ttl = new TTLDatastore(new MemoryDatastore(), undefined, { ttl: 100, frequency: 20 })
})

@@ -116,4 +113,24 @@ it('should have default options', () => {

})
it('should correctly expire batched items', async () => {
const batch = ttl.batch(100)
batch.put(key.child(new Key('1')), value)
batch.put(key.child(new Key('2')), value)
batch.put(key.child(new Key('3')), value)
await batch.commit()
let list = []
for await (const { key } of ttl.query({})) {
list.push(key)
}
expect(list).to.have.length(3)
ttl.ttl(key.child(new Key('3')), 300)
await sleep(200)
list = []
const it = ttl.query({ prefix: key.toString() })
for await (const kv of it) {
list.push(kv.key)
}
expect(list).to.have.length(1)
})
})
})
})

@@ -6,2 +6,3 @@ import { Buffer } from 'buffer'

import { pack, unpack } from 'lexicographic-integer'
import { Duration } from './duration'

@@ -11,3 +12,3 @@ const ttlPrefix = new Key('ttl')

export { Duration } from './duration'
export { Duration }

@@ -39,3 +40,3 @@ export interface TTLDatastoreOptions {

) {}
put(key: Key, value: Value, ttl?: number) {
put(key: Key, value: Value) {
this.on.push(key)

@@ -67,2 +68,3 @@ return this.batch.put(key, value)

private interval: number | NodeJS.Timeout = 0
readonly options: TTLDatastoreOptions
/**

@@ -80,4 +82,8 @@ * TTLDatastore creates a new datastore that supports TTL expirations.

private meta: Datastore<Buffer> = new NamespaceDatastore(store, ttlPrefix),
readonly options: TTLDatastoreOptions = { ttl: 0, frequency: 10000 },
options?: TTLDatastoreOptions,
) {
this.options = {
frequency: options?.frequency || Duration.Second * 10,
ttl: options?.ttl || 0,
}
this.lock = new RWLock()

@@ -95,6 +101,7 @@ this.startTTL()

// @note: ttlPrefix is required 'hack' because NamespaceDatastore doesn't take this into account
// @fixme: Assuming ttlPrefix is not a good idea, we should extract the prefix from the meta store
const lte = ttlPrefix.child(expPrefix.child(new Key(exp)))
const query: Query<Buffer> = {
prefix: expPrefix.toString(),
filters: [item => item.key.toString() <= lte.toString()],
filters: [item => item.key.less(lte)],
}

@@ -114,2 +121,3 @@ const meta = this.meta.batch()

}
return
}

@@ -116,0 +124,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc