@byearlybird/starling 0.9.2 → 0.10.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 +270 -2
- package/dist/index.js +309 -523
- package/package.json +2 -14
- package/dist/plugins/unstorage/plugin.d.ts +0 -54
- package/dist/plugins/unstorage/plugin.js +0 -104
- package/dist/store-F8qPSj_p.d.ts +0 -306
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byearlybird/starling",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Lightweight local-first data store with automatic cross-device sync. Plain JavaScript queries, framework-agnostic, zero dependencies. Offline-first apps without the complexity, in just 4KB.",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"main": "./dist/index.js",
|
|
@@ -10,11 +11,6 @@
|
|
|
10
11
|
"types": "./dist/index.d.ts",
|
|
11
12
|
"import": "./dist/index.js",
|
|
12
13
|
"default": "./dist/index.js"
|
|
13
|
-
},
|
|
14
|
-
"./plugin-unstorage": {
|
|
15
|
-
"types": "./dist/plugins/unstorage/plugin.d.ts",
|
|
16
|
-
"import": "./dist/plugins/unstorage/plugin.js",
|
|
17
|
-
"default": "./dist/plugins/unstorage/plugin.js"
|
|
18
14
|
}
|
|
19
15
|
},
|
|
20
16
|
"files": [
|
|
@@ -24,14 +20,6 @@
|
|
|
24
20
|
"build": "bun run build.ts",
|
|
25
21
|
"prepublishOnly": "bun run build.ts"
|
|
26
22
|
},
|
|
27
|
-
"peerDependencies": {
|
|
28
|
-
"unstorage": "^1.17.1"
|
|
29
|
-
},
|
|
30
|
-
"peerDependenciesMeta": {
|
|
31
|
-
"unstorage": {
|
|
32
|
-
"optional": true
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
23
|
"publishConfig": {
|
|
36
24
|
"access": "public"
|
|
37
25
|
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { c as Collection, t as Plugin } from "../../store-F8qPSj_p.js";
|
|
2
|
-
import { Storage } from "unstorage";
|
|
3
|
-
|
|
4
|
-
//#region src/plugins/unstorage/plugin.d.ts
|
|
5
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
6
|
-
type UnstorageOnBeforeSet = (data: Collection) => MaybePromise<Collection>;
|
|
7
|
-
type UnstorageOnAfterGet = (data: Collection) => MaybePromise<Collection>;
|
|
8
|
-
/**
|
|
9
|
-
* Configuration options for the unstorage persistence plugin.
|
|
10
|
-
*/
|
|
11
|
-
type UnstorageConfig = {
|
|
12
|
-
/** Delay in ms to collapse rapid mutations into a single write. Default: 0 (immediate) */
|
|
13
|
-
debounceMs?: number;
|
|
14
|
-
/** Interval in ms to poll storage for external changes. When set, enables automatic sync. */
|
|
15
|
-
pollIntervalMs?: number;
|
|
16
|
-
/** Hook invoked before persisting to storage. Use for encryption, compression, etc. */
|
|
17
|
-
onBeforeSet?: UnstorageOnBeforeSet;
|
|
18
|
-
/** Hook invoked after loading from storage. Use for decryption, validation, etc. */
|
|
19
|
-
onAfterGet?: UnstorageOnAfterGet;
|
|
20
|
-
/** Function that returns true to skip persistence operations. Use for conditional sync. */
|
|
21
|
-
skip?: () => boolean;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Persistence plugin for Starling using unstorage backends.
|
|
25
|
-
*
|
|
26
|
-
* Automatically persists store snapshots and optionally polls for external changes.
|
|
27
|
-
*
|
|
28
|
-
* @param key - Storage key for this dataset
|
|
29
|
-
* @param storage - Unstorage instance (localStorage, HTTP, filesystem, etc.)
|
|
30
|
-
* @param config - Optional configuration for debouncing, polling, hooks, and conditional sync
|
|
31
|
-
* @returns Plugin instance for store.use()
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* import { unstoragePlugin } from "@byearlybird/starling/plugin-unstorage";
|
|
36
|
-
* import { createStorage } from "unstorage";
|
|
37
|
-
* import localStorageDriver from "unstorage/drivers/localstorage";
|
|
38
|
-
*
|
|
39
|
-
* const store = await new Store<Todo>()
|
|
40
|
-
* .use(unstoragePlugin('todos', createStorage({
|
|
41
|
-
* driver: localStorageDriver({ base: 'app:' })
|
|
42
|
-
* }), {
|
|
43
|
-
* debounceMs: 300,
|
|
44
|
-
* pollIntervalMs: 5000,
|
|
45
|
-
* skip: () => !navigator.onLine
|
|
46
|
-
* }))
|
|
47
|
-
* .init();
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* @see {@link ../../../../docs/plugins/unstorage.md} for detailed configuration guide
|
|
51
|
-
*/
|
|
52
|
-
declare function unstoragePlugin<T>(key: string, storage: Storage<Collection>, config?: UnstorageConfig): Plugin<T>;
|
|
53
|
-
//#endregion
|
|
54
|
-
export { type UnstorageConfig, unstoragePlugin };
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
//#region src/plugins/unstorage/plugin.ts
|
|
2
|
-
/**
|
|
3
|
-
* Persistence plugin for Starling using unstorage backends.
|
|
4
|
-
*
|
|
5
|
-
* Automatically persists store snapshots and optionally polls for external changes.
|
|
6
|
-
*
|
|
7
|
-
* @param key - Storage key for this dataset
|
|
8
|
-
* @param storage - Unstorage instance (localStorage, HTTP, filesystem, etc.)
|
|
9
|
-
* @param config - Optional configuration for debouncing, polling, hooks, and conditional sync
|
|
10
|
-
* @returns Plugin instance for store.use()
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* import { unstoragePlugin } from "@byearlybird/starling/plugin-unstorage";
|
|
15
|
-
* import { createStorage } from "unstorage";
|
|
16
|
-
* import localStorageDriver from "unstorage/drivers/localstorage";
|
|
17
|
-
*
|
|
18
|
-
* const store = await new Store<Todo>()
|
|
19
|
-
* .use(unstoragePlugin('todos', createStorage({
|
|
20
|
-
* driver: localStorageDriver({ base: 'app:' })
|
|
21
|
-
* }), {
|
|
22
|
-
* debounceMs: 300,
|
|
23
|
-
* pollIntervalMs: 5000,
|
|
24
|
-
* skip: () => !navigator.onLine
|
|
25
|
-
* }))
|
|
26
|
-
* .init();
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* @see {@link ../../../../docs/plugins/unstorage.md} for detailed configuration guide
|
|
30
|
-
*/
|
|
31
|
-
function unstoragePlugin(key, storage, config = {}) {
|
|
32
|
-
const { debounceMs = 0, pollIntervalMs, onBeforeSet, onAfterGet, skip } = config;
|
|
33
|
-
let debounceTimer = null;
|
|
34
|
-
let pollInterval = null;
|
|
35
|
-
let store = null;
|
|
36
|
-
let persistPromise = null;
|
|
37
|
-
const persistSnapshot = async () => {
|
|
38
|
-
if (!store) return;
|
|
39
|
-
const data = store.collection();
|
|
40
|
-
const persisted = onBeforeSet !== void 0 ? await onBeforeSet(data) : data;
|
|
41
|
-
await storage.set(key, persisted);
|
|
42
|
-
};
|
|
43
|
-
const runPersist = async () => {
|
|
44
|
-
debounceTimer = null;
|
|
45
|
-
persistPromise = persistSnapshot();
|
|
46
|
-
await persistPromise;
|
|
47
|
-
persistPromise = null;
|
|
48
|
-
};
|
|
49
|
-
const schedulePersist = () => {
|
|
50
|
-
if (skip?.()) return;
|
|
51
|
-
if (debounceMs === 0) {
|
|
52
|
-
persistPromise = persistSnapshot().finally(() => {
|
|
53
|
-
persistPromise = null;
|
|
54
|
-
});
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
if (debounceTimer !== null) clearTimeout(debounceTimer);
|
|
58
|
-
debounceTimer = setTimeout(() => {
|
|
59
|
-
runPersist();
|
|
60
|
-
}, debounceMs);
|
|
61
|
-
};
|
|
62
|
-
const pollStorage = async () => {
|
|
63
|
-
if (!store) return;
|
|
64
|
-
if (skip?.()) return;
|
|
65
|
-
const persisted = await storage.get(key);
|
|
66
|
-
if (!persisted) return;
|
|
67
|
-
const data = onAfterGet !== void 0 ? await onAfterGet(persisted) : persisted;
|
|
68
|
-
store.merge(data);
|
|
69
|
-
};
|
|
70
|
-
return {
|
|
71
|
-
onInit: async (s) => {
|
|
72
|
-
store = s;
|
|
73
|
-
await pollStorage();
|
|
74
|
-
if (pollIntervalMs !== void 0 && pollIntervalMs > 0) pollInterval = setInterval(() => {
|
|
75
|
-
pollStorage();
|
|
76
|
-
}, pollIntervalMs);
|
|
77
|
-
},
|
|
78
|
-
onDispose: async () => {
|
|
79
|
-
if (debounceTimer !== null) {
|
|
80
|
-
clearTimeout(debounceTimer);
|
|
81
|
-
debounceTimer = null;
|
|
82
|
-
await runPersist();
|
|
83
|
-
}
|
|
84
|
-
if (pollInterval !== null) {
|
|
85
|
-
clearInterval(pollInterval);
|
|
86
|
-
pollInterval = null;
|
|
87
|
-
}
|
|
88
|
-
if (persistPromise !== null) await persistPromise;
|
|
89
|
-
store = null;
|
|
90
|
-
},
|
|
91
|
-
onAdd: () => {
|
|
92
|
-
schedulePersist();
|
|
93
|
-
},
|
|
94
|
-
onUpdate: () => {
|
|
95
|
-
schedulePersist();
|
|
96
|
-
},
|
|
97
|
-
onDelete: () => {
|
|
98
|
-
schedulePersist();
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
//#endregion
|
|
104
|
-
export { unstoragePlugin };
|
package/dist/store-F8qPSj_p.d.ts
DELETED
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
//#region src/crdt/value.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* A primitive value wrapped with its eventstamp for Last-Write-Wins conflict resolution.
|
|
4
|
-
* Used as the leaf nodes in the CRDT data structure.
|
|
5
|
-
*
|
|
6
|
-
* @template T - The type of the wrapped value (primitive or complex type)
|
|
7
|
-
*/
|
|
8
|
-
type EncodedValue<T> = {
|
|
9
|
-
/** The actual value being stored */
|
|
10
|
-
"~value": T;
|
|
11
|
-
/** The eventstamp indicating when this value was last written (ISO|counter|nonce) */
|
|
12
|
-
"~eventstamp": string;
|
|
13
|
-
};
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region src/crdt/record.d.ts
|
|
16
|
-
/**
|
|
17
|
-
* A nested object structure where each field is either an EncodedValue (leaf)
|
|
18
|
-
* or another EncodedRecord (nested object). This enables field-level
|
|
19
|
-
* Last-Write-Wins merging for complex data structures.
|
|
20
|
-
*
|
|
21
|
-
* Each field maintains its own eventstamp, allowing concurrent updates to
|
|
22
|
-
* different fields to be preserved during merge operations.
|
|
23
|
-
*/
|
|
24
|
-
type EncodedRecord = {
|
|
25
|
-
[key: string]: EncodedValue<unknown> | EncodedRecord;
|
|
26
|
-
};
|
|
27
|
-
//#endregion
|
|
28
|
-
//#region src/crdt/document.d.ts
|
|
29
|
-
/**
|
|
30
|
-
* Top-level document structure with system metadata for tracking identity,
|
|
31
|
-
* data, and deletion state. Documents are the primary unit of storage and
|
|
32
|
-
* synchronization in Starling.
|
|
33
|
-
*
|
|
34
|
-
* The tilde prefix (~) distinguishes system metadata from user-defined data.
|
|
35
|
-
*/
|
|
36
|
-
type EncodedDocument = {
|
|
37
|
-
/** Unique identifier for this document */
|
|
38
|
-
"~id": string;
|
|
39
|
-
/** The document's data, either a primitive value or nested object structure */
|
|
40
|
-
"~data": EncodedValue<unknown> | EncodedRecord;
|
|
41
|
-
/** Eventstamp when this document was soft-deleted, or null if not deleted */
|
|
42
|
-
"~deletedAt": string | null;
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Transform all values in a document using a provided function.
|
|
46
|
-
*
|
|
47
|
-
* Useful for custom serialization in plugin hooks (encryption, compression, etc.)
|
|
48
|
-
*
|
|
49
|
-
* @param doc - Document to transform
|
|
50
|
-
* @param process - Function to apply to each leaf value
|
|
51
|
-
* @returns New document with transformed values
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* // Encrypt all values before persisting
|
|
56
|
-
* const encrypted = processDocument(doc, (value) => ({
|
|
57
|
-
* ...value,
|
|
58
|
-
* "~value": encrypt(value["~value"])
|
|
59
|
-
* }));
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
declare function processDocument(doc: EncodedDocument, process: (value: EncodedValue<unknown>) => EncodedValue<unknown>): EncodedDocument;
|
|
63
|
-
//#endregion
|
|
64
|
-
//#region src/crdt/collection.d.ts
|
|
65
|
-
/**
|
|
66
|
-
* A collection represents the complete state of a store:
|
|
67
|
-
* - A set of documents (including soft-deleted ones)
|
|
68
|
-
* - The highest eventstamp observed across all operations
|
|
69
|
-
*
|
|
70
|
-
* Collections are the unit of synchronization between store replicas.
|
|
71
|
-
*/
|
|
72
|
-
type Collection = {
|
|
73
|
-
/** Array of encoded documents with eventstamps and metadata */
|
|
74
|
-
"~docs": EncodedDocument[];
|
|
75
|
-
/** Latest eventstamp observed by this collection for clock synchronization */
|
|
76
|
-
"~eventstamp": string;
|
|
77
|
-
};
|
|
78
|
-
//#endregion
|
|
79
|
-
//#region src/store.d.ts
|
|
80
|
-
type NotPromise<T> = T extends Promise<any> ? never : T;
|
|
81
|
-
type DeepPartial<T> = T extends object ? { [P in keyof T]?: DeepPartial<T[P]> } : T;
|
|
82
|
-
/**
|
|
83
|
-
* Options for adding documents to the store.
|
|
84
|
-
*/
|
|
85
|
-
type StoreAddOptions = {
|
|
86
|
-
/** Provide a custom ID instead of generating one */
|
|
87
|
-
withId?: string;
|
|
88
|
-
};
|
|
89
|
-
/**
|
|
90
|
-
* Configuration options for creating a Store instance.
|
|
91
|
-
*/
|
|
92
|
-
type StoreConfig = {
|
|
93
|
-
/** Custom ID generator. Defaults to crypto.randomUUID() */
|
|
94
|
-
getId?: () => string;
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Transaction context for batching multiple operations with rollback support.
|
|
98
|
-
*
|
|
99
|
-
* Transactions allow you to group multiple mutations together and optionally
|
|
100
|
-
* abort all changes if validation fails.
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```ts
|
|
104
|
-
* store.begin((tx) => {
|
|
105
|
-
* const id = tx.add({ name: 'Alice' });
|
|
106
|
-
* if (!isValid(tx.get(id))) {
|
|
107
|
-
* tx.rollback(); // Abort all changes
|
|
108
|
-
* }
|
|
109
|
-
* });
|
|
110
|
-
* ```
|
|
111
|
-
*/
|
|
112
|
-
type StoreSetTransaction<T> = {
|
|
113
|
-
/** Add a document and return its ID */
|
|
114
|
-
add: (value: T, options?: StoreAddOptions) => string;
|
|
115
|
-
/** Update a document with a partial value (field-level merge) */
|
|
116
|
-
update: (key: string, value: DeepPartial<T>) => void;
|
|
117
|
-
/** Merge an encoded document (used by sync/persistence plugins) */
|
|
118
|
-
merge: (doc: EncodedDocument) => void;
|
|
119
|
-
/** Soft-delete a document */
|
|
120
|
-
del: (key: string) => void;
|
|
121
|
-
/** Get a document within this transaction */
|
|
122
|
-
get: (key: string) => T | null;
|
|
123
|
-
/** Abort the transaction and discard all changes */
|
|
124
|
-
rollback: () => void;
|
|
125
|
-
};
|
|
126
|
-
/**
|
|
127
|
-
* Plugin interface for extending store behavior with persistence, analytics, etc.
|
|
128
|
-
*
|
|
129
|
-
* All hooks are optional. Mutation hooks receive batched entries after each
|
|
130
|
-
* transaction commits.
|
|
131
|
-
*
|
|
132
|
-
* @example
|
|
133
|
-
* ```ts
|
|
134
|
-
* const loggingPlugin: Plugin<Todo> = {
|
|
135
|
-
* onInit: async () => console.log('Store initialized'),
|
|
136
|
-
* onAdd: (entries) => console.log('Added:', entries.length),
|
|
137
|
-
* onDispose: async () => console.log('Store disposed')
|
|
138
|
-
* };
|
|
139
|
-
* ```
|
|
140
|
-
*/
|
|
141
|
-
type Plugin<T> = {
|
|
142
|
-
/** Called once when store.init() runs */
|
|
143
|
-
onInit: (store: Store<T>) => Promise<void> | void;
|
|
144
|
-
/** Called once when store.dispose() runs */
|
|
145
|
-
onDispose: () => Promise<void> | void;
|
|
146
|
-
/** Called after documents are added (batched per transaction) */
|
|
147
|
-
onAdd?: (entries: ReadonlyArray<readonly [string, T]>) => void;
|
|
148
|
-
/** Called after documents are updated (batched per transaction) */
|
|
149
|
-
onUpdate?: (entries: ReadonlyArray<readonly [string, T]>) => void;
|
|
150
|
-
/** Called after documents are deleted (batched per transaction) */
|
|
151
|
-
onDelete?: (keys: ReadonlyArray<string>) => void;
|
|
152
|
-
};
|
|
153
|
-
/**
|
|
154
|
-
* Configuration for creating a reactive query.
|
|
155
|
-
*
|
|
156
|
-
* Queries automatically update when matching documents change.
|
|
157
|
-
*
|
|
158
|
-
* @example
|
|
159
|
-
* ```ts
|
|
160
|
-
* const config: QueryConfig<Todo> = {
|
|
161
|
-
* where: (todo) => !todo.completed,
|
|
162
|
-
* select: (todo) => todo.text,
|
|
163
|
-
* order: (a, b) => a.localeCompare(b)
|
|
164
|
-
* };
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
type QueryConfig<T, U = T> = {
|
|
168
|
-
/** Filter predicate - return true to include document in results */
|
|
169
|
-
where: (data: T) => boolean;
|
|
170
|
-
/** Optional projection - transform documents before returning */
|
|
171
|
-
select?: (data: T) => U;
|
|
172
|
-
/** Optional comparator for stable ordering of results */
|
|
173
|
-
order?: (a: U, b: U) => number;
|
|
174
|
-
};
|
|
175
|
-
/**
|
|
176
|
-
* A reactive query handle that tracks matching documents and notifies on changes.
|
|
177
|
-
*
|
|
178
|
-
* Call `dispose()` when done to clean up listeners and remove from the store.
|
|
179
|
-
*/
|
|
180
|
-
type Query<U> = {
|
|
181
|
-
/** Get current matching documents as [id, document] tuples */
|
|
182
|
-
results: () => Array<readonly [string, U]>;
|
|
183
|
-
/** Register a change listener. Returns unsubscribe function. */
|
|
184
|
-
onChange: (callback: () => void) => () => void;
|
|
185
|
-
/** Remove this query from the store and clear all listeners */
|
|
186
|
-
dispose: () => void;
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* Lightweight local-first data store with built-in sync and reactive queries.
|
|
190
|
-
*
|
|
191
|
-
* Stores plain JavaScript objects with automatic field-level conflict resolution
|
|
192
|
-
* using Last-Write-Wins semantics powered by hybrid logical clocks.
|
|
193
|
-
*
|
|
194
|
-
* @template T - The type of documents stored in this collection
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```ts
|
|
198
|
-
* const store = await new Store<{ text: string; completed: boolean }>()
|
|
199
|
-
* .use(unstoragePlugin('todos', storage))
|
|
200
|
-
* .init();
|
|
201
|
-
*
|
|
202
|
-
* // Add, update, delete
|
|
203
|
-
* const id = store.add({ text: 'Buy milk', completed: false });
|
|
204
|
-
* store.update(id, { completed: true });
|
|
205
|
-
* store.del(id);
|
|
206
|
-
*
|
|
207
|
-
* // Reactive queries
|
|
208
|
-
* const activeTodos = store.query({ where: (todo) => !todo.completed });
|
|
209
|
-
* activeTodos.onChange(() => console.log('Todos changed!'));
|
|
210
|
-
* ```
|
|
211
|
-
*/
|
|
212
|
-
declare class Store<T> {
|
|
213
|
-
#private;
|
|
214
|
-
constructor(config?: StoreConfig);
|
|
215
|
-
/**
|
|
216
|
-
* Get a document by ID.
|
|
217
|
-
* @returns The document, or null if not found or deleted
|
|
218
|
-
*/
|
|
219
|
-
get(key: string): T | null;
|
|
220
|
-
/**
|
|
221
|
-
* Iterate over all non-deleted documents as [id, document] tuples.
|
|
222
|
-
*/
|
|
223
|
-
entries(): IterableIterator<readonly [string, T]>;
|
|
224
|
-
/**
|
|
225
|
-
* Get the complete store state as a Collection for persistence or sync.
|
|
226
|
-
* @returns Collection containing all documents and the latest eventstamp
|
|
227
|
-
*/
|
|
228
|
-
collection(): Collection;
|
|
229
|
-
/**
|
|
230
|
-
* Merge a collection from storage or another replica using field-level LWW.
|
|
231
|
-
* @param collection - Collection from storage or another store instance
|
|
232
|
-
*/
|
|
233
|
-
merge(collection: Collection): void;
|
|
234
|
-
/**
|
|
235
|
-
* Run multiple operations in a transaction with rollback support.
|
|
236
|
-
*
|
|
237
|
-
* @param callback - Function receiving a transaction context
|
|
238
|
-
* @param opts - Optional config. Use `silent: true` to skip plugin hooks.
|
|
239
|
-
* @returns The callback's return value
|
|
240
|
-
*
|
|
241
|
-
* @example
|
|
242
|
-
* ```ts
|
|
243
|
-
* const id = store.begin((tx) => {
|
|
244
|
-
* const newId = tx.add({ text: 'Buy milk' });
|
|
245
|
-
* tx.update(newId, { priority: 'high' });
|
|
246
|
-
* return newId; // Return value becomes begin()'s return value
|
|
247
|
-
* });
|
|
248
|
-
* ```
|
|
249
|
-
*/
|
|
250
|
-
begin<R = void>(callback: (tx: StoreSetTransaction<T>) => NotPromise<R>, opts?: {
|
|
251
|
-
silent?: boolean;
|
|
252
|
-
}): NotPromise<R>;
|
|
253
|
-
/**
|
|
254
|
-
* Add a document to the store.
|
|
255
|
-
* @returns The document's ID (generated or provided via options)
|
|
256
|
-
*/
|
|
257
|
-
add(value: T, options?: StoreAddOptions): string;
|
|
258
|
-
/**
|
|
259
|
-
* Update a document with a partial value.
|
|
260
|
-
*
|
|
261
|
-
* Uses field-level merge - only specified fields are updated.
|
|
262
|
-
*/
|
|
263
|
-
update(key: string, value: DeepPartial<T>): void;
|
|
264
|
-
/**
|
|
265
|
-
* Soft-delete a document.
|
|
266
|
-
*
|
|
267
|
-
* Deleted docs remain in snapshots for sync purposes but are
|
|
268
|
-
* excluded from queries and reads.
|
|
269
|
-
*/
|
|
270
|
-
del(key: string): void;
|
|
271
|
-
/**
|
|
272
|
-
* Register a plugin for persistence, analytics, etc.
|
|
273
|
-
* @returns This store instance for chaining
|
|
274
|
-
*/
|
|
275
|
-
use(plugin: Plugin<T>): this;
|
|
276
|
-
/**
|
|
277
|
-
* Initialize the store and run plugin onInit hooks.
|
|
278
|
-
*
|
|
279
|
-
* Must be called before using the store. Runs plugin setup (hydrate
|
|
280
|
-
* snapshots, start pollers, etc.) and hydrates existing queries.
|
|
281
|
-
*
|
|
282
|
-
* @returns This store instance for chaining
|
|
283
|
-
*/
|
|
284
|
-
init(): Promise<this>;
|
|
285
|
-
/**
|
|
286
|
-
* Dispose the store and run plugin cleanup.
|
|
287
|
-
*
|
|
288
|
-
* Flushes pending operations, clears queries, and runs plugin teardown.
|
|
289
|
-
* Call when shutting down to avoid memory leaks.
|
|
290
|
-
*/
|
|
291
|
-
dispose(): Promise<void>;
|
|
292
|
-
/**
|
|
293
|
-
* Create a reactive query that auto-updates when matching docs change.
|
|
294
|
-
*
|
|
295
|
-
* @example
|
|
296
|
-
* ```ts
|
|
297
|
-
* const active = store.query({ where: (todo) => !todo.completed });
|
|
298
|
-
* active.results(); // [[id, todo], ...]
|
|
299
|
-
* active.onChange(() => console.log('Updated!'));
|
|
300
|
-
* active.dispose(); // Clean up when done
|
|
301
|
-
* ```
|
|
302
|
-
*/
|
|
303
|
-
query<U = T>(config: QueryConfig<T, U>): Query<U>;
|
|
304
|
-
}
|
|
305
|
-
//#endregion
|
|
306
|
-
export { StoreAddOptions as a, Collection as c, EncodedRecord as d, EncodedValue as f, Store as i, EncodedDocument as l, Query as n, StoreConfig as o, QueryConfig as r, StoreSetTransaction as s, Plugin as t, processDocument as u };
|