AbstractAbstractgetRetrieves a value from storage by key.
Returns the stored value deserialized to the specified type, or null if the key doesn't exist or the value is null.
Values are automatically deserialized using SuperJSON, which properly restores Date objects, Maps, Sets, and other complex types.
The expected type of the stored value (must be Serializable)
The storage key to retrieve
Promise resolving to the stored value or null
AbstractsetStores a value in persistent storage.
The value will be serialized using SuperJSON and stored persistently. Any existing value at the same key will be overwritten.
SuperJSON automatically handles Date objects, Maps, Sets, undefined values, and other complex types that standard JSON doesn't support.
The type of value being stored (must be Serializable)
The storage key to use
The value to store (must be SuperJSON-serializable)
Promise that resolves when the value is stored
// Date objects are preserved
await this.set('sync_state', {
lastSync: new Date(),
minDate: new Date(2024, 0, 1)
});
// undefined is now supported
await this.set('data', { name: 'test', optional: undefined }); // ✅ Works
// Arrays with undefined are supported
await this.set('items', [1, undefined, 3]); // ✅ Works
await this.set('items', [1, null, 3]); // ✅ Also works
// Maps and Sets are supported
await this.set('mapping', new Map([['key', 'value']])); // ✅ Works
await this.set('tags', new Set(['tag1', 'tag2'])); // ✅ Works
// Functions are NOT supported - use callback tokens instead
const token = await this.callback(this.myFunction);
await this.set('callback_ref', token); // ✅ Use callback token
AbstractlistLists all storage keys matching a prefix.
Returns an array of key strings that start with the given prefix. Useful for finding all keys in a namespace (e.g., all sync locks).
The prefix to match keys against
Promise resolving to an array of matching key strings
AbstractclearRemoves a specific key from storage.
After this operation, get() calls for this key will return null. No error is thrown if the key doesn't exist.
The storage key to remove
Promise that resolves when the key is removed
AbstractclearRemoves all keys from this storage instance.
This operation clears all data stored by this twist/tool instance but does not affect storage for other twists or tools.
Promise that resolves when all keys are removed
AbstractacquireAcquire a self-expiring lock. Returns true if the caller now holds the lock, false if another holder has a non-expired lease.
Use this for any operation where you previously hand-rolled a boolean
"in progress" flag with manual cleanup on every error path. The lock
auto-releases after ttlMs, so a crashed/timed-out holder cannot wedge
the system permanently — pick a ttlMs comfortably longer than the
worst-case duration of the protected work.
Acquisition is atomic across concurrent callers (the underlying
Durable Object serializes operations). Lock keys live in a reserved
namespace and never appear in get / list results.
Lock identifier (any string).
Lease duration in milliseconds. After this time the lock
is considered expired and a new caller can acquire it even if
releaseLock was never called.
Promise resolving to true if acquired, false if held.
AbstractreleaseRelease a lock acquired via acquireLock. Safe to call even if the caller never acquired the lock or the lease has already expired.
The same key that was passed to acquireLock.
Built-in tool for persistent key-value storage.
The Store tool provides twists and tools with a simple, persistent storage mechanism that survives worker restarts and invocations. Each twist/tool instance gets its own isolated storage namespace.
Note: Store methods are also available directly on Twist and Tool classes via
this.get(),this.set(),this.clear(), andthis.clearAll(). This is the recommended approach for most use cases.Storage Characteristics:
Supported Data Types (via SuperJSON):
NOT Supported (will throw validation errors):
Use Cases:
Example