@lunora/client 1.0.0-alpha.2 → 1.0.0-alpha.21
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/LICENSE.md +6 -0
- package/README.md +2 -0
- package/__assets__/package-og.svg +1 -1
- package/dist/auth/index.d.mts +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/index.d.mts +144 -24
- package/dist/index.d.ts +144 -24
- package/dist/index.mjs +10 -9
- package/dist/packem_shared/CONFLICT_ERROR_CODE-B8gQ8tyU.mjs +33 -0
- package/dist/packem_shared/{DEFAULT_MAX_BUFFER-BDkqO5PW.mjs → DEFAULT_MAX_BUFFER-7hFnzNk9.mjs} +6 -3
- package/dist/packem_shared/{LunoraClient-UiULzH_1.mjs → LunoraClient-kXpHNyaE.mjs} +1562 -267
- package/dist/packem_shared/OfflineQueue-GGYJRmhF.mjs +1 -0
- package/dist/packem_shared/SubscriptionRegistry-DjGKZsqq.mjs +1 -0
- package/dist/packem_shared/{applyDelta-4jFGTPA3.mjs → applyDelta-CRKZ1PBt.mjs} +21 -1
- package/dist/packem_shared/createInMemoryPersistence-DZ2VHWgm.mjs +79 -0
- package/dist/packem_shared/{createInMemoryQueryCache-B1PQ9Twl.mjs → createInMemoryQueryCache-DiaGZkA2.mjs} +25 -51
- package/dist/packem_shared/createLocalStore-jRoqmazl.mjs +2 -0
- package/dist/packem_shared/createMutatorRunner-BETvCd0p.mjs +31 -0
- package/dist/packem_shared/{createServerClient-BjZc3gD8.mjs → createServerClient-DF-3mLmb.mjs} +1 -1
- package/dist/packem_shared/idb-utility-DrSVX43Q.mjs +48 -0
- package/dist/packem_shared/local-store-BveBeFEo.mjs +106 -0
- package/dist/packem_shared/{lunora-client.d-DGvyuJ_p.d.mts → lunora-client.d-BYkEjCEJ.d.mts} +1001 -58
- package/dist/packem_shared/{lunora-client.d-DGvyuJ_p.d.ts → lunora-client.d-BYkEjCEJ.d.ts} +1001 -58
- package/dist/packem_shared/{OfflineQueue-D5p_QgF_.mjs → offline-queue-B9vfdSqp.mjs} +49 -6
- package/dist/packem_shared/{preload.d-BoDmFqSG.d.ts → preload.d-B-vyHnml.d.ts} +1 -1
- package/dist/packem_shared/{preload.d-dSaRMuhL.d.mts → preload.d-DrfuisCE.d.mts} +1 -1
- package/dist/packem_shared/subscription-BjynOXCU.mjs +68 -0
- package/dist/query/index.d.mts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/ssr/index.d.mts +3 -3
- package/dist/ssr/index.d.ts +3 -3
- package/dist/ssr/index.mjs +1 -1
- package/package.json +5 -2
- package/dist/packem_shared/CONFLICT_ERROR_CODE-aUdVbEDw.mjs +0 -4
- package/dist/packem_shared/SubscriptionRegistry-B-Qx_Gux.mjs +0 -26
- package/dist/packem_shared/createInMemoryPersistence-CW82inU5.mjs +0 -105
- package/dist/packem_shared/createLocalStore-DSUfoLqY.mjs +0 -36
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { O as OfflineQueue, n as nextId, r as reportPersistenceError } from './offline-queue-B9vfdSqp.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { S as SubscriptionRegistry } from './subscription-BjynOXCU.mjs';
|
|
@@ -7,14 +7,34 @@ const rowId = (row) => {
|
|
|
7
7
|
const id = row[ID_FIELD];
|
|
8
8
|
return typeof id === "string" ? id : void 0;
|
|
9
9
|
};
|
|
10
|
+
const isDescending = (list) => {
|
|
11
|
+
let previous;
|
|
12
|
+
for (const existingRow of list) {
|
|
13
|
+
const existing = existingRow[CREATION_FIELD];
|
|
14
|
+
if (typeof existing !== "number") {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (previous !== void 0) {
|
|
18
|
+
if (existing < previous) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (existing > previous) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
previous = existing;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
10
29
|
const insertionIndex = (list, row) => {
|
|
11
30
|
const creation = row[CREATION_FIELD];
|
|
12
31
|
if (typeof creation !== "number") {
|
|
13
32
|
return list.length;
|
|
14
33
|
}
|
|
34
|
+
const descending = isDescending(list);
|
|
15
35
|
for (const [index, existingRow] of list.entries()) {
|
|
16
36
|
const existing = existingRow[CREATION_FIELD];
|
|
17
|
-
if (typeof existing === "number" && existing > creation) {
|
|
37
|
+
if (typeof existing === "number" && (descending ? existing < creation : existing > creation)) {
|
|
18
38
|
return index;
|
|
19
39
|
}
|
|
20
40
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
import { p as promisifyRequest, c as createWithStore, a as createDatabaseOpener } from './idb-utility-DrSVX43Q.mjs';
|
|
3
|
+
|
|
4
|
+
const createInMemoryPersistence = () => {
|
|
5
|
+
const entries = /* @__PURE__ */ new Map();
|
|
6
|
+
const clone = (mutation) => {
|
|
7
|
+
return {
|
|
8
|
+
args: { ...mutation.args },
|
|
9
|
+
functionPath: mutation.functionPath,
|
|
10
|
+
id: mutation.id,
|
|
11
|
+
identity: mutation.identity,
|
|
12
|
+
shardKey: mutation.shardKey
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
append: (mutation) => {
|
|
17
|
+
entries.set(mutation.id, clone(mutation));
|
|
18
|
+
return Promise.resolve();
|
|
19
|
+
},
|
|
20
|
+
clear: () => {
|
|
21
|
+
entries.clear();
|
|
22
|
+
return Promise.resolve();
|
|
23
|
+
},
|
|
24
|
+
load: () => Promise.resolve([...entries.values()].map((mutation) => clone(mutation))),
|
|
25
|
+
remove: (id) => {
|
|
26
|
+
entries.delete(id);
|
|
27
|
+
return Promise.resolve();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const DEFAULT_DATABASE = "lunora-outbox";
|
|
32
|
+
const DEFAULT_STORE = "offline-mutations";
|
|
33
|
+
const ID_INDEX = "by_id";
|
|
34
|
+
const createIndexedDbPersistence = (options = {}) => {
|
|
35
|
+
const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
|
|
36
|
+
if (!factory) {
|
|
37
|
+
throw new LunoraError("INTERNAL", "createIndexedDbPersistence: no IndexedDB available — pass `indexedDB` or use createInMemoryPersistence()");
|
|
38
|
+
}
|
|
39
|
+
const databaseName = options.databaseName ?? DEFAULT_DATABASE;
|
|
40
|
+
const storeName = options.storeName ?? DEFAULT_STORE;
|
|
41
|
+
const openDatabase = createDatabaseOpener(factory, databaseName, 1, (database) => {
|
|
42
|
+
if (!database.objectStoreNames.contains(storeName)) {
|
|
43
|
+
const store = database.createObjectStore(storeName, { autoIncrement: true });
|
|
44
|
+
store.createIndex(ID_INDEX, "id", { unique: true });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const withStore = createWithStore(openDatabase, storeName);
|
|
48
|
+
return {
|
|
49
|
+
append: async (mutation) => {
|
|
50
|
+
await withStore("readwrite", (store) => promisifyRequest(store.add(mutation)));
|
|
51
|
+
},
|
|
52
|
+
clear: async () => {
|
|
53
|
+
await withStore("readwrite", (store) => promisifyRequest(store.clear()));
|
|
54
|
+
},
|
|
55
|
+
load: async () => withStore("readonly", (store) => promisifyRequest(store.getAll())),
|
|
56
|
+
remove: async (id) => {
|
|
57
|
+
await withStore("readwrite", async (store) => {
|
|
58
|
+
const key = await promisifyRequest(store.index(ID_INDEX).getKey(id));
|
|
59
|
+
if (key !== void 0) {
|
|
60
|
+
await promisifyRequest(store.delete(key));
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
const resolvePersistenceAdapter = (option, autoProbe = true) => {
|
|
67
|
+
if (option === false) {
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
if (option) {
|
|
71
|
+
return option;
|
|
72
|
+
}
|
|
73
|
+
if (!autoProbe || typeof indexedDB === "undefined") {
|
|
74
|
+
return void 0;
|
|
75
|
+
}
|
|
76
|
+
return createIndexedDbPersistence();
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { createInMemoryPersistence, createIndexedDbPersistence, resolvePersistenceAdapter };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
import { p as promisifyRequest, c as createWithStore, a as createDatabaseOpener } from './idb-utility-DrSVX43Q.mjs';
|
|
3
|
+
|
|
1
4
|
const queryCacheKey = (functionPath, argsKey, shardKey) => `${functionPath}::${argsKey}::${shardKey ?? ""}`;
|
|
2
5
|
const DEFAULT_MAX_ENTRIES = 500;
|
|
3
6
|
const createInMemoryQueryCache = (options = {}) => {
|
|
@@ -35,66 +38,25 @@ const createInMemoryQueryCache = (options = {}) => {
|
|
|
35
38
|
}
|
|
36
39
|
};
|
|
37
40
|
};
|
|
38
|
-
const DEFAULT_DATABASE = "lunora";
|
|
41
|
+
const DEFAULT_DATABASE = "lunora-query-cache";
|
|
39
42
|
const DEFAULT_STORE = "query-cache";
|
|
40
43
|
const TS_INDEX = "by_ts";
|
|
41
|
-
const DATABASE_VERSION =
|
|
42
|
-
const promisifyRequest = (request) => new Promise((resolve, reject) => {
|
|
43
|
-
request.addEventListener("success", () => {
|
|
44
|
-
resolve(request.result);
|
|
45
|
-
});
|
|
46
|
-
request.addEventListener("error", () => {
|
|
47
|
-
reject(request.error ?? new Error("IndexedDB request failed"));
|
|
48
|
-
});
|
|
49
|
-
});
|
|
44
|
+
const DATABASE_VERSION = 1;
|
|
50
45
|
const createIndexedDbQueryCache = (options = {}) => {
|
|
51
46
|
const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
|
|
52
47
|
if (!factory) {
|
|
53
|
-
throw new
|
|
48
|
+
throw new LunoraError("INTERNAL", "createIndexedDbQueryCache: no IndexedDB available — pass `indexedDB` or use createInMemoryQueryCache()");
|
|
54
49
|
}
|
|
55
50
|
const databaseName = options.databaseName ?? DEFAULT_DATABASE;
|
|
56
51
|
const storeName = options.storeName ?? DEFAULT_STORE;
|
|
57
52
|
const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
const openDatabase = createDatabaseOpener(factory, databaseName, DATABASE_VERSION, (database) => {
|
|
54
|
+
if (!database.objectStoreNames.contains(storeName)) {
|
|
55
|
+
const store = database.createObjectStore(storeName, { keyPath: "key" });
|
|
56
|
+
store.createIndex(TS_INDEX, "ts", { unique: false });
|
|
62
57
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
request.addEventListener("upgradeneeded", () => {
|
|
66
|
-
const database = request.result;
|
|
67
|
-
if (!database.objectStoreNames.contains(storeName)) {
|
|
68
|
-
const store = database.createObjectStore(storeName, { keyPath: "key" });
|
|
69
|
-
store.createIndex(TS_INDEX, "ts", { unique: false });
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
request.addEventListener("success", () => {
|
|
73
|
-
resolve(request.result);
|
|
74
|
-
});
|
|
75
|
-
request.addEventListener("error", () => {
|
|
76
|
-
reject(request.error ?? new Error("IndexedDB open failed"));
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
return databasePromise;
|
|
80
|
-
};
|
|
81
|
-
const withStore = async (mode, run) => {
|
|
82
|
-
const database = await openDatabase();
|
|
83
|
-
const transaction = database.transaction(storeName, mode);
|
|
84
|
-
const result = await run(transaction.objectStore(storeName));
|
|
85
|
-
await new Promise((resolve, reject) => {
|
|
86
|
-
transaction.addEventListener("complete", () => {
|
|
87
|
-
resolve();
|
|
88
|
-
});
|
|
89
|
-
transaction.addEventListener("error", () => {
|
|
90
|
-
reject(transaction.error ?? new Error("IndexedDB transaction failed"));
|
|
91
|
-
});
|
|
92
|
-
transaction.addEventListener("abort", () => {
|
|
93
|
-
reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
return result;
|
|
97
|
-
};
|
|
58
|
+
});
|
|
59
|
+
const withStore = createWithStore(openDatabase, storeName);
|
|
98
60
|
const evict = async (store) => {
|
|
99
61
|
const count = await promisifyRequest(store.count());
|
|
100
62
|
let overflow = count - maxEntries;
|
|
@@ -134,5 +96,17 @@ const createIndexedDbQueryCache = (options = {}) => {
|
|
|
134
96
|
}
|
|
135
97
|
};
|
|
136
98
|
};
|
|
99
|
+
const resolveQueryCacheAdapter = (option) => {
|
|
100
|
+
if (option === false) {
|
|
101
|
+
return void 0;
|
|
102
|
+
}
|
|
103
|
+
if (option) {
|
|
104
|
+
return option;
|
|
105
|
+
}
|
|
106
|
+
if (typeof indexedDB === "undefined") {
|
|
107
|
+
return void 0;
|
|
108
|
+
}
|
|
109
|
+
return createIndexedDbQueryCache();
|
|
110
|
+
};
|
|
137
111
|
|
|
138
|
-
export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey };
|
|
112
|
+
export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey, resolveQueryCacheAdapter };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const createMutatorRunner = (handle, sinks) => {
|
|
2
|
+
let inFlight = 0;
|
|
3
|
+
let latestInvocation = 0;
|
|
4
|
+
const mutate = async (args) => {
|
|
5
|
+
latestInvocation += 1;
|
|
6
|
+
const invocation = latestInvocation;
|
|
7
|
+
inFlight += 1;
|
|
8
|
+
sinks.setPending(true);
|
|
9
|
+
try {
|
|
10
|
+
await handle(args).isPersisted.promise;
|
|
11
|
+
if (invocation === latestInvocation) {
|
|
12
|
+
sinks.setError(void 0);
|
|
13
|
+
}
|
|
14
|
+
} catch (error) {
|
|
15
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
16
|
+
if (invocation === latestInvocation) {
|
|
17
|
+
sinks.setError(normalized);
|
|
18
|
+
}
|
|
19
|
+
throw normalized;
|
|
20
|
+
} finally {
|
|
21
|
+
inFlight -= 1;
|
|
22
|
+
sinks.setPending(inFlight > 0);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const reset = () => {
|
|
26
|
+
sinks.setError(void 0);
|
|
27
|
+
};
|
|
28
|
+
return { mutate, reset };
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { createMutatorRunner };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const promisifyRequest = (request) => new Promise((resolve, reject) => {
|
|
2
|
+
request.addEventListener("success", () => {
|
|
3
|
+
resolve(request.result);
|
|
4
|
+
});
|
|
5
|
+
request.addEventListener("error", () => {
|
|
6
|
+
reject(request.error ?? new Error("IndexedDB request failed"));
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
const createDatabaseOpener = (factory, databaseName, version, upgrade) => {
|
|
10
|
+
let databasePromise;
|
|
11
|
+
return () => {
|
|
12
|
+
if (databasePromise) {
|
|
13
|
+
return databasePromise;
|
|
14
|
+
}
|
|
15
|
+
databasePromise = new Promise((resolve, reject) => {
|
|
16
|
+
const request = factory.open(databaseName, version);
|
|
17
|
+
request.addEventListener("upgradeneeded", () => {
|
|
18
|
+
upgrade(request.result);
|
|
19
|
+
});
|
|
20
|
+
request.addEventListener("success", () => {
|
|
21
|
+
resolve(request.result);
|
|
22
|
+
});
|
|
23
|
+
request.addEventListener("error", () => {
|
|
24
|
+
reject(request.error ?? new Error("IndexedDB open failed"));
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
return databasePromise;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const createWithStore = (open, storeName) => async (mode, run) => {
|
|
31
|
+
const database = await open();
|
|
32
|
+
const transaction = database.transaction(storeName, mode);
|
|
33
|
+
const result = await run(transaction.objectStore(storeName));
|
|
34
|
+
await new Promise((resolve, reject) => {
|
|
35
|
+
transaction.addEventListener("complete", () => {
|
|
36
|
+
resolve();
|
|
37
|
+
});
|
|
38
|
+
transaction.addEventListener("error", () => {
|
|
39
|
+
reject(transaction.error ?? new Error("IndexedDB transaction failed"));
|
|
40
|
+
});
|
|
41
|
+
transaction.addEventListener("abort", () => {
|
|
42
|
+
reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { createDatabaseOpener as a, createWithStore as c, promisifyRequest as p };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { S as SubscriptionRegistry } from './subscription-BjynOXCU.mjs';
|
|
2
|
+
|
|
3
|
+
const foldOptimistic = (base, layers) => {
|
|
4
|
+
let value = base;
|
|
5
|
+
for (const layer of layers) {
|
|
6
|
+
try {
|
|
7
|
+
value = layer.transform(value);
|
|
8
|
+
} catch {
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
const notifySubscription = (state, value) => {
|
|
14
|
+
if (value === state.lastValue) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
state.lastValue = value;
|
|
18
|
+
for (const callback of state.callbacks) {
|
|
19
|
+
try {
|
|
20
|
+
callback(value);
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const applyOptimisticLayer = (state, optimistic) => {
|
|
26
|
+
let next;
|
|
27
|
+
try {
|
|
28
|
+
next = optimistic(state.lastValue);
|
|
29
|
+
} catch {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
const layer = { id: /* @__PURE__ */ Symbol("optimistic"), transform: optimistic };
|
|
33
|
+
state.optimisticLayers.push(layer);
|
|
34
|
+
notifySubscription(state, next);
|
|
35
|
+
const remove = () => {
|
|
36
|
+
const index = state.optimisticLayers.findIndex((entry) => entry.id === layer.id);
|
|
37
|
+
if (index === -1) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
state.optimisticLayers.splice(index, 1);
|
|
41
|
+
return true;
|
|
42
|
+
};
|
|
43
|
+
const refold = () => {
|
|
44
|
+
notifySubscription(state, foldOptimistic(state.serverBase, state.optimisticLayers));
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
confirm: (commitCursor) => {
|
|
48
|
+
if (commitCursor === void 0) {
|
|
49
|
+
remove();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
layer.commitCursor = commitCursor;
|
|
53
|
+
if (state.serverCursor !== void 0 && state.serverCursor >= commitCursor && remove()) {
|
|
54
|
+
refold();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
rollback: () => {
|
|
58
|
+
if (remove()) {
|
|
59
|
+
refold();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
const dropConfirmedLayers = (state, cursor) => {
|
|
65
|
+
if (cursor === void 0 || state.optimisticLayers.length === 0) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const before = state.optimisticLayers.length;
|
|
69
|
+
state.optimisticLayers = state.optimisticLayers.filter((layer) => layer.commitCursor === void 0 || layer.commitCursor > cursor);
|
|
70
|
+
return state.optimisticLayers.length !== before;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const createLocalStore = (subscriptions, shardKey) => {
|
|
74
|
+
const confirms = [];
|
|
75
|
+
const rollbacks = [];
|
|
76
|
+
const findState = (functionRef, args) => subscriptions.get(SubscriptionRegistry.key(functionRef, args, shardKey));
|
|
77
|
+
const store = {
|
|
78
|
+
getAllQueries: (function_) => {
|
|
79
|
+
const matches = [];
|
|
80
|
+
for (const state of subscriptions.all()) {
|
|
81
|
+
if (state.fn.__lunoraRef === function_.__lunoraRef && (state.shardKey ?? "") === (shardKey ?? "")) {
|
|
82
|
+
matches.push({ args: state.args, value: state.lastValue });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return matches;
|
|
86
|
+
},
|
|
87
|
+
getQuery: (function_, args) => {
|
|
88
|
+
const state = findState(function_.__lunoraRef, args ?? {});
|
|
89
|
+
return state?.lastValue;
|
|
90
|
+
},
|
|
91
|
+
setQuery: (function_, args, value) => {
|
|
92
|
+
const state = findState(function_.__lunoraRef, args ?? {});
|
|
93
|
+
if (!state) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const handle = applyOptimisticLayer(state, () => value);
|
|
97
|
+
if (handle) {
|
|
98
|
+
confirms.push(handle.confirm);
|
|
99
|
+
rollbacks.push(handle.rollback);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
return { confirms, rollbacks, store };
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export { applyOptimisticLayer as a, createLocalStore as c, dropConfirmedLayers as d, foldOptimistic as f, notifySubscription as n };
|