@lunora/client 1.0.0-alpha.28 → 1.0.0-alpha.29

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.
Files changed (77) hide show
  1. package/dist/auth/index.d.mts +1 -1
  2. package/dist/auth/index.d.ts +1 -1
  3. package/dist/auth/index.mjs +1 -60
  4. package/dist/index.d.mts +3 -3
  5. package/dist/index.d.ts +3 -3
  6. package/dist/index.mjs +1 -21
  7. package/dist/packem_shared/CONFLICT_ERROR_CODE-B2SU0CaJ.mjs +1 -0
  8. package/dist/packem_shared/ClientServiceWorker-CRQ5yl7-.mjs +1 -0
  9. package/dist/packem_shared/DEFAULT_MAX_BUFFER-TBn2s7Rz.mjs +1 -0
  10. package/dist/packem_shared/LunoraClient-DDEoZdgP.mjs +1 -0
  11. package/dist/packem_shared/OfflineQueue-B603_q8m.mjs +1 -0
  12. package/dist/packem_shared/SKIP-CArzT3Vl.mjs +1 -0
  13. package/dist/packem_shared/SubscriptionRegistry-CdrOD7sZ.mjs +1 -0
  14. package/dist/packem_shared/TabCoordinator-ijLic02x.mjs +1 -0
  15. package/dist/packem_shared/applyDelta-DXqQORbM.mjs +1 -0
  16. package/dist/packem_shared/createAsyncStoragePersistence-BRLqeXsC.mjs +1 -0
  17. package/dist/packem_shared/createClientQuery-CrdRoicO.mjs +1 -0
  18. package/dist/packem_shared/createInMemoryBookmarkStorage-DCd5Ej-t.mjs +1 -0
  19. package/dist/packem_shared/createInMemoryPersistence-CQYXy8UP.mjs +1 -0
  20. package/dist/packem_shared/createInMemoryQueryCache-DjCKrLjk.mjs +1 -0
  21. package/dist/packem_shared/createLocalStore-B3Tw_Tw1.mjs +1 -0
  22. package/dist/packem_shared/createMutationRunner-lQXH8Amk.mjs +1 -0
  23. package/dist/packem_shared/createMutatorRunner-BVzo0FBZ.mjs +1 -0
  24. package/dist/packem_shared/createReconnect-CFT7YRSR.mjs +1 -0
  25. package/dist/packem_shared/createReply-DF0jRsv-.mjs +1 -0
  26. package/dist/packem_shared/createServerClient-B7KqO8tv.mjs +1 -0
  27. package/dist/packem_shared/createSnapshotPrecondition-DOKRAJ4b.mjs +1 -0
  28. package/dist/packem_shared/deserializePreloaded-CHfOFpka.mjs +1 -0
  29. package/dist/packem_shared/getServerSession-CGjgRBAE.mjs +1 -0
  30. package/dist/packem_shared/httpStream-Cz4_QyjV.mjs +11 -0
  31. package/dist/packem_shared/idb-utility-C-DR8nG1.mjs +1 -0
  32. package/dist/packem_shared/local-store-C53xDvEr.mjs +1 -0
  33. package/dist/packem_shared/{lunora-client.d-B1iZb2Ph.d.mts → lunora-client.d-Bt65hm_E.d.mts} +135 -1
  34. package/dist/packem_shared/{lunora-client.d-B1iZb2Ph.d.ts → lunora-client.d-Bt65hm_E.d.ts} +135 -1
  35. package/dist/packem_shared/offline-queue-D73Dq95V.mjs +1 -0
  36. package/dist/packem_shared/{preload.d-CLwoXl3R.d.mts → preload.d-BmztUzzG.d.mts} +1 -1
  37. package/dist/packem_shared/{preload.d-Cqb4Kh2I.d.ts → preload.d-DGGRMWB5.d.ts} +1 -1
  38. package/dist/packem_shared/preloadQuery-DjwSjFwt.mjs +1 -0
  39. package/dist/packem_shared/wire-key-D_zOxXK4.mjs +1 -0
  40. package/dist/pagination/index.mjs +1 -61
  41. package/dist/query/index.d.mts +2 -2
  42. package/dist/query/index.d.ts +2 -2
  43. package/dist/query/index.mjs +1 -1
  44. package/dist/ssr/index.d.mts +3 -3
  45. package/dist/ssr/index.d.ts +3 -3
  46. package/dist/ssr/index.mjs +1 -4
  47. package/dist/upload.mjs +1 -24
  48. package/package.json +1 -1
  49. package/dist/packem_shared/CONFLICT_ERROR_CODE-B8gQ8tyU.mjs +0 -33
  50. package/dist/packem_shared/ClientServiceWorker-C3PAFwy0.mjs +0 -100
  51. package/dist/packem_shared/DEFAULT_MAX_BUFFER-7hFnzNk9.mjs +0 -110
  52. package/dist/packem_shared/LunoraClient-DKATLGHY.mjs +0 -3631
  53. package/dist/packem_shared/OfflineQueue-BgarnAub.mjs +0 -1
  54. package/dist/packem_shared/SKIP-vItZChkw.mjs +0 -50
  55. package/dist/packem_shared/SubscriptionRegistry-CxS_Inha.mjs +0 -31
  56. package/dist/packem_shared/TabCoordinator-D_5oNTTt.mjs +0 -258
  57. package/dist/packem_shared/applyDelta-CRKZ1PBt.mjs +0 -81
  58. package/dist/packem_shared/createAsyncStoragePersistence-1Z5BZ8RC.mjs +0 -45
  59. package/dist/packem_shared/createClientQuery-dJZg1ohm.mjs +0 -80
  60. package/dist/packem_shared/createInMemoryBookmarkStorage-BoN7a7TH.mjs +0 -11
  61. package/dist/packem_shared/createInMemoryPersistence-DZ2VHWgm.mjs +0 -79
  62. package/dist/packem_shared/createInMemoryQueryCache-DiaGZkA2.mjs +0 -112
  63. package/dist/packem_shared/createLocalStore-BtqUmOQA.mjs +0 -2
  64. package/dist/packem_shared/createMutationRunner-BqsavzvG.mjs +0 -21
  65. package/dist/packem_shared/createMutatorRunner-BETvCd0p.mjs +0 -31
  66. package/dist/packem_shared/createReconnect-Di_-oHH7.mjs +0 -22
  67. package/dist/packem_shared/createReply-lI4tVS2w.mjs +0 -36
  68. package/dist/packem_shared/createServerClient-Bp2r9tcB.mjs +0 -11
  69. package/dist/packem_shared/createSnapshotPrecondition-CxQ1T4ZP.mjs +0 -18
  70. package/dist/packem_shared/deserializePreloaded-C0eJTY_W.mjs +0 -4
  71. package/dist/packem_shared/getServerSession-8jXewqxd.mjs +0 -13
  72. package/dist/packem_shared/httpStream-DIdL8NEw.mjs +0 -168
  73. package/dist/packem_shared/idb-utility-DrSVX43Q.mjs +0 -48
  74. package/dist/packem_shared/local-store-DIq-UWfD.mjs +0 -106
  75. package/dist/packem_shared/offline-queue-N-1JvYb4.mjs +0 -211
  76. package/dist/packem_shared/preloadQuery-lobFkD2Z.mjs +0 -13
  77. package/dist/packem_shared/wire-key-Djie6aaR.mjs +0 -266
@@ -1,112 +0,0 @@
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 queryCacheKey = (functionPath, argsKey, shardKey) => `${functionPath}::${argsKey}::${shardKey ?? ""}`;
5
- const DEFAULT_MAX_ENTRIES = 500;
6
- const createInMemoryQueryCache = (options = {}) => {
7
- const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
8
- const entries = /* @__PURE__ */ new Map();
9
- const clone = (entry) => {
10
- return { ...entry, value: structuredClone(entry.value) };
11
- };
12
- const evict = () => {
13
- if (entries.size <= maxEntries) {
14
- return;
15
- }
16
- const ordered = [...entries.values()].toSorted((a, b) => a.ts - b.ts);
17
- for (const entry of ordered) {
18
- if (entries.size <= maxEntries) {
19
- break;
20
- }
21
- entries.delete(entry.key);
22
- }
23
- };
24
- return {
25
- clear: () => {
26
- entries.clear();
27
- return Promise.resolve();
28
- },
29
- load: () => Promise.resolve([...entries.values()].map((entry) => clone(entry))),
30
- put: (key, entry) => {
31
- entries.set(key, clone({ ...entry, key }));
32
- evict();
33
- return Promise.resolve();
34
- },
35
- remove: (key) => {
36
- entries.delete(key);
37
- return Promise.resolve();
38
- }
39
- };
40
- };
41
- const DEFAULT_DATABASE = "lunora-query-cache";
42
- const DEFAULT_STORE = "query-cache";
43
- const TS_INDEX = "by_ts";
44
- const DATABASE_VERSION = 1;
45
- const createIndexedDbQueryCache = (options = {}) => {
46
- const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
47
- if (!factory) {
48
- throw new LunoraError("INTERNAL", "createIndexedDbQueryCache: no IndexedDB available — pass `indexedDB` or use createInMemoryQueryCache()");
49
- }
50
- const databaseName = options.databaseName ?? DEFAULT_DATABASE;
51
- const storeName = options.storeName ?? DEFAULT_STORE;
52
- const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
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 });
57
- }
58
- });
59
- const withStore = createWithStore(openDatabase, storeName);
60
- const evict = async (store) => {
61
- const count = await promisifyRequest(store.count());
62
- let overflow = count - maxEntries;
63
- if (overflow <= 0) {
64
- return;
65
- }
66
- await new Promise((resolve, reject) => {
67
- const cursorRequest = store.index(TS_INDEX).openCursor();
68
- cursorRequest.addEventListener("success", () => {
69
- const cursor = cursorRequest.result;
70
- if (!cursor || overflow <= 0) {
71
- resolve();
72
- return;
73
- }
74
- cursor.delete();
75
- overflow -= 1;
76
- cursor.continue();
77
- });
78
- cursorRequest.addEventListener("error", () => {
79
- reject(cursorRequest.error ?? new Error("IndexedDB eviction failed"));
80
- });
81
- });
82
- };
83
- return {
84
- clear: async () => {
85
- await withStore("readwrite", (store) => promisifyRequest(store.clear()));
86
- },
87
- load: async () => withStore("readonly", (store) => promisifyRequest(store.getAll())),
88
- put: async (key, entry) => {
89
- await withStore("readwrite", async (store) => {
90
- await promisifyRequest(store.put({ ...entry, key }));
91
- await evict(store);
92
- });
93
- },
94
- remove: async (key) => {
95
- await withStore("readwrite", (store) => promisifyRequest(store.delete(key)));
96
- }
97
- };
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
- };
111
-
112
- export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey, resolveQueryCacheAdapter };
@@ -1,2 +0,0 @@
1
- export { c as createLocalStore } from './local-store-DIq-UWfD.mjs';
2
- import './SubscriptionRegistry-CxS_Inha.mjs';
@@ -1,21 +0,0 @@
1
- const createMutationRunner = (client, function_, sinks) => {
2
- let inFlight = 0;
3
- return async (args, options) => {
4
- inFlight += 1;
5
- sinks.setPending(true);
6
- try {
7
- const result = await client.mutation(function_, args, options);
8
- sinks.setResult(result);
9
- return result;
10
- } catch (error) {
11
- const normalized = error instanceof Error ? error : new Error(String(error));
12
- sinks.setError(normalized);
13
- throw normalized;
14
- } finally {
15
- inFlight -= 1;
16
- sinks.setPending(inFlight > 0);
17
- }
18
- };
19
- };
20
-
21
- export { createMutationRunner };
@@ -1,31 +0,0 @@
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 };
@@ -1,22 +0,0 @@
1
- const createReconnect = (options = {}, random = Math.random) => {
2
- const initialDelayMs = options.initialDelayMs ?? 250;
3
- const maxDelayMs = options.maxDelayMs ?? 3e4;
4
- const jitter = options.jitter ?? true;
5
- let attempt = 0;
6
- return {
7
- next() {
8
- const exponential = Math.min(maxDelayMs, initialDelayMs * 2 ** attempt);
9
- attempt += 1;
10
- if (!jitter) {
11
- return exponential;
12
- }
13
- const min = exponential / 2;
14
- return Math.floor(min + random() * (exponential - min));
15
- },
16
- reset() {
17
- attempt = 0;
18
- }
19
- };
20
- };
21
-
22
- export { createReconnect };
@@ -1,36 +0,0 @@
1
- const sendToSw = (sw, message, expectResponse = false) => new Promise((resolve, reject) => {
2
- if (!sw) {
3
- reject(new Error("No active service worker"));
4
- return;
5
- }
6
- const id = message.correlationId ?? crypto.randomUUID();
7
- const outgoingMessage = { ...message, correlationId: id };
8
- if (expectResponse) {
9
- let timer;
10
- const handler = (event) => {
11
- if (event.data.correlationId === id) {
12
- clearTimeout(timer);
13
- navigator.serviceWorker.removeEventListener("message", handler);
14
- resolve(event.data.payload);
15
- }
16
- };
17
- timer = setTimeout(() => {
18
- navigator.serviceWorker.removeEventListener("message", handler);
19
- reject(new Error(`SW message ${id} timed out`));
20
- }, 3e4);
21
- navigator.serviceWorker.addEventListener("message", handler);
22
- sw.postMessage(outgoingMessage);
23
- } else {
24
- sw.postMessage(outgoingMessage);
25
- resolve(void 0);
26
- }
27
- });
28
- const createReply = (original, payload) => {
29
- return {
30
- type: `${original.type}:reply`,
31
- payload,
32
- correlationId: original.correlationId
33
- };
34
- };
35
-
36
- export { createReply, sendToSw };
@@ -1,11 +0,0 @@
1
- import { LunoraClient } from './LunoraClient-DKATLGHY.mjs';
2
-
3
- const createServerClient = (options) => {
4
- const client = new LunoraClient({ fetch: options.fetch, url: options.url });
5
- if (options.token !== void 0) {
6
- client.setAuthToken(options.token);
7
- }
8
- return client;
9
- };
10
-
11
- export { createServerClient };
@@ -1,18 +0,0 @@
1
- import { s as stableWireKey } from './wire-key-Djie6aaR.mjs';
2
-
3
- const createSnapshotPrecondition = (client, functionRef, args, shardKey) => {
4
- const snapshot = client.peekActiveQueryValue(functionRef.__lunoraRef, args, shardKey);
5
- const snapshotKey = snapshot === void 0 ? void 0 : stableWireKey(snapshot);
6
- return () => {
7
- const current = client.peekActiveQueryValue(functionRef.__lunoraRef, args, shardKey);
8
- if (snapshotKey === void 0 && current === void 0) {
9
- return true;
10
- }
11
- if (snapshotKey === void 0 || current === void 0) {
12
- return false;
13
- }
14
- return stableWireKey(current) === snapshotKey;
15
- };
16
- };
17
-
18
- export { createSnapshotPrecondition as default };
@@ -1,4 +0,0 @@
1
- const serializePreloaded = (preloaded) => JSON.stringify(preloaded).replaceAll("<", String.raw`\u003c`);
2
- const deserializePreloaded = (serialized) => JSON.parse(serialized);
3
-
4
- export { deserializePreloaded, serializePreloaded };
@@ -1,13 +0,0 @@
1
- const extractHeaders = (source) => {
2
- if (source instanceof Headers) {
3
- return source;
4
- }
5
- return source.headers;
6
- };
7
- const getServerSession = async (request, auth) => {
8
- const headers = extractHeaders(request);
9
- const result = await auth.api.getSession({ headers });
10
- return result ?? null;
11
- };
12
-
13
- export { getServerSession };
@@ -1,168 +0,0 @@
1
- import { LunoraError } from '@lunora/errors';
2
- import { createStream } from './DEFAULT_MAX_BUFFER-7hFnzNk9.mjs';
3
-
4
- const SSE_FIELD_SPACE_RE = /^ /u;
5
- const parameterToString = (value) => typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
6
- const parseSseFrame = (raw) => {
7
- let event = "";
8
- const dataLines = [];
9
- for (const line of raw.split("\n")) {
10
- if (line.startsWith("event:")) {
11
- event = line.slice("event:".length).replace(SSE_FIELD_SPACE_RE, "");
12
- } else if (line.startsWith("data:")) {
13
- dataLines.push(line.slice("data:".length).replace(SSE_FIELD_SPACE_RE, ""));
14
- }
15
- }
16
- return { data: dataLines.join("\n"), event };
17
- };
18
- const buildHttpStreamUrl = (route, args, baseUrl) => {
19
- const parameters = args.params ?? {};
20
- const path = route.path.split("/").map((segment) => {
21
- if (!segment.startsWith(":")) {
22
- return segment;
23
- }
24
- const name = segment.slice(1);
25
- const value = parameters[name];
26
- if (value === void 0) {
27
- throw new LunoraError("HTTP_STREAM_MISSING_PARAM", `httpStream: missing path param ":${name}" for route ${route.path}`);
28
- }
29
- return encodeURIComponent(parameterToString(value));
30
- }).join("/");
31
- const search = new URLSearchParams();
32
- for (const [key, value] of Object.entries(args.searchParams ?? {})) {
33
- if (value !== void 0) {
34
- search.set(key, parameterToString(value));
35
- }
36
- }
37
- const query = search.toString();
38
- const trimmedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
39
- return `${trimmedBase}${path}${query === "" ? "" : `?${query}`}`;
40
- };
41
- const handleSseFrame = (frame, handle) => {
42
- if (frame.event === "complete") {
43
- handle.complete();
44
- return true;
45
- }
46
- if (frame.event === "error") {
47
- let payload = {};
48
- try {
49
- payload = JSON.parse(frame.data);
50
- } catch {
51
- }
52
- const message = typeof payload.message === "string" ? payload.message : "stream error";
53
- const code = typeof payload.code === "string" ? payload.code : "HTTP_STREAM_ERROR";
54
- handle.fail(new LunoraError(code, message));
55
- return true;
56
- }
57
- if ((frame.event === "" || frame.event === "message") && frame.data !== "") {
58
- try {
59
- handle.push(JSON.parse(frame.data));
60
- } catch {
61
- handle.fail(new LunoraError("HTTP_STREAM_BAD_CHUNK", "httpStream: malformed SSE chunk (invalid JSON)"));
62
- return true;
63
- }
64
- }
65
- return false;
66
- };
67
- const pumpSseBody = async (body, handle) => {
68
- const reader = body.getReader();
69
- const decoder = new TextDecoder();
70
- let buffer = "";
71
- const drainFrames = () => {
72
- let separatorIndex = buffer.indexOf("\n\n");
73
- while (separatorIndex !== -1) {
74
- const frame = parseSseFrame(buffer.slice(0, separatorIndex));
75
- buffer = buffer.slice(separatorIndex + 2);
76
- if (handleSseFrame(frame, handle)) {
77
- return true;
78
- }
79
- separatorIndex = buffer.indexOf("\n\n");
80
- }
81
- return false;
82
- };
83
- for (; ; ) {
84
- const { done, value } = await reader.read();
85
- if (done) {
86
- break;
87
- }
88
- buffer += decoder.decode(value, { stream: true }).replaceAll("\r\n", "\n");
89
- if (drainFrames()) {
90
- await reader.cancel().catch(() => {
91
- });
92
- return;
93
- }
94
- }
95
- buffer += decoder.decode().replaceAll("\r\n", "\n");
96
- if (!drainFrames()) {
97
- handle.fail(new LunoraError("HTTP_STREAM_INTERRUPTED", "httpStream: stream ended without a complete frame"));
98
- }
99
- };
100
- const httpStream = (route, args, options = {}) => {
101
- const fetchImpl = options.fetch ?? (typeof fetch === "function" ? fetch.bind(globalThis) : void 0);
102
- if (!fetchImpl) {
103
- throw new LunoraError("INTERNAL", "httpStream: no `fetch` implementation available");
104
- }
105
- const url = buildHttpStreamUrl(route, args ?? {}, options.baseUrl ?? "");
106
- const ac = new AbortController();
107
- let onExternalAbort;
108
- if (options.signal) {
109
- if (options.signal.aborted) {
110
- ac.abort();
111
- } else {
112
- onExternalAbort = () => {
113
- ac.abort();
114
- };
115
- options.signal.addEventListener("abort", onExternalAbort, { once: true });
116
- }
117
- }
118
- const detachExternalAbort = () => {
119
- if (onExternalAbort) {
120
- options.signal?.removeEventListener("abort", onExternalAbort);
121
- }
122
- };
123
- const { handle, iterable } = createStream({
124
- maxBuffer: options.maxBuffer,
125
- onCancel: () => {
126
- ac.abort();
127
- }
128
- });
129
- (async () => {
130
- try {
131
- const response = await fetchImpl(url, {
132
- headers: { accept: "text/event-stream", ...options.headers },
133
- method: route.method,
134
- signal: ac.signal
135
- });
136
- if (!response.ok) {
137
- await response.body?.cancel().catch(() => {
138
- });
139
- handle.fail(
140
- new LunoraError("HTTP_STREAM_STATUS", `httpStream: request failed (status ${response.status.toString()})`, {
141
- status: response.status
142
- })
143
- );
144
- return;
145
- }
146
- if (!response.body) {
147
- handle.fail(new LunoraError("HTTP_STREAM_NO_BODY", "httpStream: response has no body"));
148
- return;
149
- }
150
- await pumpSseBody(response.body, handle);
151
- } finally {
152
- detachExternalAbort();
153
- }
154
- })().catch((error) => {
155
- if (ac.signal.aborted) {
156
- handle.complete();
157
- return;
158
- }
159
- if (error instanceof Error && "code" in error) {
160
- handle.fail(error);
161
- return;
162
- }
163
- handle.fail(new LunoraError("HTTP_STREAM_TRANSPORT", error instanceof Error ? error.message : String(error), { cause: error }));
164
- });
165
- return iterable;
166
- };
167
-
168
- export { httpStream };
@@ -1,48 +0,0 @@
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 };
@@ -1,106 +0,0 @@
1
- import { SubscriptionRegistry } from './SubscriptionRegistry-CxS_Inha.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 };