@byearlybird/starling 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +20 -36
- package/dist/index.js +31 -77
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -75,9 +75,14 @@ declare const create$1: (iterable?: Iterable<readonly [string, EncodedDocument]>
|
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
77
|
declare namespace store_d_exports {
|
|
78
|
-
export {
|
|
78
|
+
export { DeepPartial, NotPromise, Plugin, PluginMethods, Store as StarlingStore, StoreHooks, StoreOnDelete, StoreOnPatch, StoreOnPut, StorePutOptions, StoreSetTransaction, create };
|
|
79
79
|
}
|
|
80
80
|
type DeepPartial<T$1> = T$1 extends object ? { [P in keyof T$1]?: DeepPartial<T$1[P]> } : T$1;
|
|
81
|
+
/**
|
|
82
|
+
* Type constraint to prevent Promise returns from set callbacks.
|
|
83
|
+
* Transactions must be synchronous operations.
|
|
84
|
+
*/
|
|
85
|
+
type NotPromise<T$1> = T$1 extends Promise<any> ? never : T$1;
|
|
81
86
|
/**
|
|
82
87
|
* Called once per commit with all put operations accumulated as decoded entries.
|
|
83
88
|
* Only fires if at least one put occurred.
|
|
@@ -93,68 +98,47 @@ type StoreOnPatch<T$1> = (entries: ReadonlyArray<readonly [string, T$1]>) => voi
|
|
|
93
98
|
* Only fires if at least one delete occurred.
|
|
94
99
|
*/
|
|
95
100
|
type StoreOnDelete = (keys: ReadonlyArray<string>) => void;
|
|
96
|
-
/**
|
|
97
|
-
* Called before a put operation is applied.
|
|
98
|
-
* Throws to reject the operation.
|
|
99
|
-
*/
|
|
100
|
-
type StoreOnBeforePut<T$1> = (key: string, value: T$1) => void;
|
|
101
|
-
/**
|
|
102
|
-
* Called before a patch operation is applied.
|
|
103
|
-
* Throws to reject the operation.
|
|
104
|
-
*/
|
|
105
|
-
type StoreOnBeforePatch<T$1> = (key: string, value: DeepPartial<T$1>) => void;
|
|
106
|
-
/**
|
|
107
|
-
* Called before a delete operation is applied.
|
|
108
|
-
* Throws to reject the operation.
|
|
109
|
-
*/
|
|
110
|
-
type StoreOnBeforeDelete = (key: string) => void;
|
|
111
101
|
/**
|
|
112
102
|
* Hook callbacks that receive batches of decoded entries.
|
|
113
103
|
* Hooks fire on commit only, never during staged operations.
|
|
114
104
|
* Arrays are readonly to prevent external mutation.
|
|
115
105
|
*/
|
|
116
106
|
type StoreHooks<T$1> = {
|
|
117
|
-
onBeforePut?: StoreOnBeforePut<T$1>;
|
|
118
|
-
onBeforePatch?: StoreOnBeforePatch<T$1>;
|
|
119
|
-
onBeforeDelete?: StoreOnBeforeDelete;
|
|
120
107
|
onPut?: StoreOnPut<T$1>;
|
|
121
108
|
onPatch?: StoreOnPatch<T$1>;
|
|
122
109
|
onDelete?: StoreOnDelete;
|
|
123
110
|
};
|
|
124
|
-
type
|
|
125
|
-
|
|
111
|
+
type StorePutOptions = {
|
|
112
|
+
withId?: string;
|
|
113
|
+
};
|
|
114
|
+
type StoreSetTransaction<T$1> = {
|
|
115
|
+
put: (value: T$1, options?: StorePutOptions) => string;
|
|
126
116
|
patch: (key: string, value: DeepPartial<T$1>) => void;
|
|
127
117
|
merge: (doc: EncodedDocument) => void;
|
|
128
118
|
del: (key: string) => void;
|
|
129
|
-
|
|
130
|
-
commit: (opts?: {
|
|
131
|
-
silent: boolean;
|
|
132
|
-
}) => void;
|
|
119
|
+
get: (key: string) => T$1 | null;
|
|
133
120
|
rollback: () => void;
|
|
134
121
|
};
|
|
135
122
|
type PluginMethods = Record<string, (...args: any[]) => any>;
|
|
136
|
-
type
|
|
137
|
-
init: () => Promise<void> | void;
|
|
123
|
+
type Plugin<T$1, M$1 extends PluginMethods = {}> = {
|
|
124
|
+
init: (store: Store<T$1>) => Promise<void> | void;
|
|
138
125
|
dispose: () => Promise<void> | void;
|
|
139
126
|
hooks?: StoreHooks<T$1>;
|
|
140
127
|
methods?: M$1;
|
|
141
128
|
};
|
|
142
|
-
type Plugin<T$1, M$1 extends PluginMethods = {}> = (store: Store<T$1, any>) => PluginHandle<T$1, M$1>;
|
|
143
129
|
type Store<T$1, Extended = {}> = {
|
|
144
130
|
get: (key: string) => T$1 | null;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
131
|
+
set: <R = void>(callback: (tx: StoreSetTransaction<T$1>) => NotPromise<R>, opts?: {
|
|
132
|
+
silent?: boolean;
|
|
133
|
+
}) => NotPromise<R>;
|
|
148
134
|
entries: () => IterableIterator<readonly [string, T$1]>;
|
|
149
135
|
snapshot: () => EncodedDocument[];
|
|
150
|
-
put: (key: string, value: T$1) => void;
|
|
151
|
-
patch: (key: string, value: DeepPartial<T$1>) => void;
|
|
152
|
-
del: (key: string) => void;
|
|
153
|
-
begin: () => StoreTransaction<T$1>;
|
|
154
136
|
use: <M extends PluginMethods>(plugin: Plugin<T$1, M>) => Store<T$1, Extended & M>;
|
|
155
137
|
init: () => Promise<Store<T$1, Extended>>;
|
|
156
138
|
dispose: () => Promise<void>;
|
|
157
139
|
} & Extended;
|
|
158
|
-
declare const create: <T>(
|
|
140
|
+
declare const create: <T>(config?: {
|
|
141
|
+
getId?: () => string;
|
|
142
|
+
}) => Store<T, {}>;
|
|
159
143
|
//#endregion
|
|
160
144
|
export { type clock_d_exports as Clock, document_d_exports as Document, eventstamp_d_exports as Eventstamp, kv_d_exports as KV, record_d_exports as Record, store_d_exports as Store, value_d_exports as Value };
|
package/dist/index.js
CHANGED
|
@@ -226,20 +226,18 @@ const create$1 = (iterable) => {
|
|
|
226
226
|
//#endregion
|
|
227
227
|
//#region src/store.ts
|
|
228
228
|
var store_exports = /* @__PURE__ */ __export({ create: () => create });
|
|
229
|
-
const create = () => {
|
|
229
|
+
const create = (config = {}) => {
|
|
230
230
|
const kv = create$1();
|
|
231
231
|
const clock = create$2();
|
|
232
|
+
const initializers = /* @__PURE__ */ new Set();
|
|
233
|
+
const disposers = /* @__PURE__ */ new Set();
|
|
234
|
+
const getId = config.getId ?? (() => crypto.randomUUID());
|
|
232
235
|
const encodeValue = (key, value) => encode(key, value, clock.now());
|
|
233
236
|
const listeners = {
|
|
234
|
-
beforePut: /* @__PURE__ */ new Set(),
|
|
235
|
-
beforePatch: /* @__PURE__ */ new Set(),
|
|
236
|
-
beforeDel: /* @__PURE__ */ new Set(),
|
|
237
237
|
put: /* @__PURE__ */ new Set(),
|
|
238
238
|
patch: /* @__PURE__ */ new Set(),
|
|
239
239
|
del: /* @__PURE__ */ new Set()
|
|
240
240
|
};
|
|
241
|
-
const initializers = /* @__PURE__ */ new Set();
|
|
242
|
-
const disposers = /* @__PURE__ */ new Set();
|
|
243
241
|
const decodeActive = (doc) => {
|
|
244
242
|
if (!doc || doc["~deletedAt"]) return null;
|
|
245
243
|
return decode(doc)["~data"];
|
|
@@ -248,18 +246,6 @@ const create = () => {
|
|
|
248
246
|
get(key) {
|
|
249
247
|
return decodeActive(kv.get(key));
|
|
250
248
|
},
|
|
251
|
-
has(key) {
|
|
252
|
-
return decodeActive(kv.get(key)) !== null;
|
|
253
|
-
},
|
|
254
|
-
values() {
|
|
255
|
-
function* iterator() {
|
|
256
|
-
for (const doc of kv.values()) {
|
|
257
|
-
const data = decodeActive(doc);
|
|
258
|
-
if (data !== null) yield data;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return iterator();
|
|
262
|
-
},
|
|
263
249
|
entries() {
|
|
264
250
|
function* iterator() {
|
|
265
251
|
for (const [key, doc] of kv.entries()) {
|
|
@@ -272,45 +258,27 @@ const create = () => {
|
|
|
272
258
|
snapshot() {
|
|
273
259
|
return Array.from(kv.values());
|
|
274
260
|
},
|
|
275
|
-
|
|
276
|
-
let count = 0;
|
|
277
|
-
for (const doc of kv.values()) if (doc && !doc["~deletedAt"]) count++;
|
|
278
|
-
return count;
|
|
279
|
-
},
|
|
280
|
-
put(key, value) {
|
|
281
|
-
const tx = this.begin();
|
|
282
|
-
tx.put(key, value);
|
|
283
|
-
tx.commit();
|
|
284
|
-
},
|
|
285
|
-
patch(key, value) {
|
|
286
|
-
const tx = this.begin();
|
|
287
|
-
tx.patch(key, value);
|
|
288
|
-
tx.commit();
|
|
289
|
-
},
|
|
290
|
-
del(key) {
|
|
291
|
-
const tx = this.begin();
|
|
292
|
-
tx.del(key);
|
|
293
|
-
tx.commit();
|
|
294
|
-
},
|
|
295
|
-
begin() {
|
|
261
|
+
set(callback, opts) {
|
|
296
262
|
const tx = kv.begin();
|
|
263
|
+
const silent = opts?.silent ?? false;
|
|
297
264
|
const putKeyValues = [];
|
|
298
265
|
const patchKeyValues = [];
|
|
299
266
|
const deleteKeys = [];
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
267
|
+
let rolledBack = false;
|
|
268
|
+
const setTransaction = {
|
|
269
|
+
put(value, options) {
|
|
270
|
+
const key = options?.withId ?? getId();
|
|
303
271
|
tx.put(key, encodeValue(key, value));
|
|
304
272
|
putKeyValues.push([key, value]);
|
|
273
|
+
return key;
|
|
305
274
|
},
|
|
306
275
|
patch(key, value) {
|
|
307
|
-
for (const fn of listeners.beforePatch) fn(key, value);
|
|
308
276
|
tx.patch(key, encode(key, value, clock.now()));
|
|
309
277
|
const merged = decodeActive(tx.get(key));
|
|
310
278
|
if (merged) patchKeyValues.push([key, merged]);
|
|
311
279
|
},
|
|
312
280
|
merge(doc) {
|
|
313
|
-
if (tx.
|
|
281
|
+
if (tx.get(doc["~id"])) tx.patch(doc["~id"], doc);
|
|
314
282
|
else tx.put(doc["~id"], doc);
|
|
315
283
|
const currentDoc = tx.get(doc["~id"]);
|
|
316
284
|
if (currentDoc && !currentDoc["~deletedAt"]) {
|
|
@@ -319,50 +287,36 @@ const create = () => {
|
|
|
319
287
|
}
|
|
320
288
|
},
|
|
321
289
|
del(key) {
|
|
322
|
-
for (const fn of listeners.beforeDel) fn(key);
|
|
323
290
|
if (!tx.get(key)) return;
|
|
324
291
|
tx.del(key, clock.now());
|
|
325
292
|
deleteKeys.push(key);
|
|
326
293
|
},
|
|
327
|
-
|
|
328
|
-
return tx.
|
|
329
|
-
},
|
|
330
|
-
commit(opts = { silent: false }) {
|
|
331
|
-
tx.commit();
|
|
332
|
-
if (opts.silent) return;
|
|
333
|
-
if (putKeyValues.length > 0) for (const fn of listeners.put) fn(Object.freeze([...putKeyValues]));
|
|
334
|
-
if (patchKeyValues.length > 0) for (const fn of listeners.patch) fn(Object.freeze([...patchKeyValues]));
|
|
335
|
-
if (deleteKeys.length > 0) for (const fn of listeners.del) fn(Object.freeze([...deleteKeys]));
|
|
294
|
+
get(key) {
|
|
295
|
+
return decodeActive(tx.get(key));
|
|
336
296
|
},
|
|
337
297
|
rollback() {
|
|
298
|
+
rolledBack = true;
|
|
338
299
|
tx.rollback();
|
|
339
300
|
}
|
|
340
301
|
};
|
|
302
|
+
try {
|
|
303
|
+
const result = callback(setTransaction);
|
|
304
|
+
if (rolledBack) return result;
|
|
305
|
+
tx.commit();
|
|
306
|
+
if (!silent) {
|
|
307
|
+
if (putKeyValues.length > 0) for (const fn of listeners.put) fn(Object.freeze([...putKeyValues]));
|
|
308
|
+
if (patchKeyValues.length > 0) for (const fn of listeners.patch) fn(Object.freeze([...patchKeyValues]));
|
|
309
|
+
if (deleteKeys.length > 0) for (const fn of listeners.del) fn(Object.freeze([...deleteKeys]));
|
|
310
|
+
}
|
|
311
|
+
return result;
|
|
312
|
+
} catch (error) {
|
|
313
|
+
tx.rollback();
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
341
316
|
},
|
|
342
317
|
use(plugin) {
|
|
343
|
-
const { hooks: pluginHooks, init, dispose, methods } = plugin
|
|
318
|
+
const { hooks: pluginHooks, init, dispose, methods } = plugin;
|
|
344
319
|
if (pluginHooks) {
|
|
345
|
-
if (pluginHooks.onBeforePut) {
|
|
346
|
-
const callback = pluginHooks.onBeforePut;
|
|
347
|
-
listeners.beforePut.add(callback);
|
|
348
|
-
disposers.add(() => {
|
|
349
|
-
listeners.beforePut.delete(callback);
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
if (pluginHooks.onBeforePatch) {
|
|
353
|
-
const callback = pluginHooks.onBeforePatch;
|
|
354
|
-
listeners.beforePatch.add(callback);
|
|
355
|
-
disposers.add(() => {
|
|
356
|
-
listeners.beforePatch.delete(callback);
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
if (pluginHooks.onBeforeDelete) {
|
|
360
|
-
const callback = pluginHooks.onBeforeDelete;
|
|
361
|
-
listeners.beforeDel.add(callback);
|
|
362
|
-
disposers.add(() => {
|
|
363
|
-
listeners.beforeDel.delete(callback);
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
320
|
if (pluginHooks.onPut) {
|
|
367
321
|
const callback = pluginHooks.onPut;
|
|
368
322
|
listeners.put.add(callback);
|
|
@@ -391,7 +345,7 @@ const create = () => {
|
|
|
391
345
|
return this;
|
|
392
346
|
},
|
|
393
347
|
async init() {
|
|
394
|
-
for (const fn of initializers) await fn();
|
|
348
|
+
for (const fn of initializers) await fn(this);
|
|
395
349
|
return this;
|
|
396
350
|
},
|
|
397
351
|
async dispose() {
|