@lunora/client 1.0.0-alpha.2 → 1.0.0-alpha.20

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 (34) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +2 -0
  3. package/__assets__/package-og.svg +1 -1
  4. package/dist/auth/index.d.mts +1 -1
  5. package/dist/auth/index.d.ts +1 -1
  6. package/dist/index.d.mts +144 -24
  7. package/dist/index.d.ts +144 -24
  8. package/dist/index.mjs +9 -8
  9. package/dist/packem_shared/CONFLICT_ERROR_CODE-B8gQ8tyU.mjs +33 -0
  10. package/dist/packem_shared/{DEFAULT_MAX_BUFFER-BDkqO5PW.mjs → DEFAULT_MAX_BUFFER-7hFnzNk9.mjs} +6 -3
  11. package/dist/packem_shared/{LunoraClient-UiULzH_1.mjs → LunoraClient-hrmLXEHd.mjs} +1512 -266
  12. package/dist/packem_shared/OfflineQueue-GGYJRmhF.mjs +1 -0
  13. package/dist/packem_shared/SubscriptionRegistry-Cxr70og-.mjs +1 -0
  14. package/dist/packem_shared/{createInMemoryPersistence-CW82inU5.mjs → createInMemoryPersistence-Ds7z8n8d.mjs} +17 -3
  15. package/dist/packem_shared/{createInMemoryQueryCache-B1PQ9Twl.mjs → createInMemoryQueryCache-iWtKPrid.mjs} +18 -4
  16. package/dist/packem_shared/createLocalStore-IOur0jHF.mjs +1 -0
  17. package/dist/packem_shared/createMutatorRunner-BETvCd0p.mjs +31 -0
  18. package/dist/packem_shared/{createServerClient-BjZc3gD8.mjs → createServerClient-CKKZrXLc.mjs} +1 -1
  19. package/dist/packem_shared/local-store-BNgN3Dw3.mjs +111 -0
  20. package/dist/packem_shared/{lunora-client.d-DGvyuJ_p.d.mts → lunora-client.d-DVdVtJV8.d.mts} +973 -58
  21. package/dist/packem_shared/{lunora-client.d-DGvyuJ_p.d.ts → lunora-client.d-DVdVtJV8.d.ts} +973 -58
  22. package/dist/packem_shared/{OfflineQueue-D5p_QgF_.mjs → offline-queue-B9vfdSqp.mjs} +49 -6
  23. package/dist/packem_shared/{preload.d-dSaRMuhL.d.mts → preload.d-BXFvxpiv.d.mts} +1 -1
  24. package/dist/packem_shared/{preload.d-BoDmFqSG.d.ts → preload.d-Bb69VRgE.d.ts} +1 -1
  25. package/dist/packem_shared/subscription-DoyO04-2.mjs +65 -0
  26. package/dist/query/index.d.mts +2 -2
  27. package/dist/query/index.d.ts +2 -2
  28. package/dist/ssr/index.d.mts +3 -3
  29. package/dist/ssr/index.d.ts +3 -3
  30. package/dist/ssr/index.mjs +1 -1
  31. package/package.json +5 -2
  32. package/dist/packem_shared/CONFLICT_ERROR_CODE-aUdVbEDw.mjs +0 -4
  33. package/dist/packem_shared/SubscriptionRegistry-B-Qx_Gux.mjs +0 -26
  34. 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-DoyO04-2.mjs';
@@ -1,3 +1,5 @@
1
+ import { LunoraError } from '@lunora/errors';
2
+
1
3
  const createInMemoryPersistence = () => {
2
4
  const entries = /* @__PURE__ */ new Map();
3
5
  const clone = (mutation) => {
@@ -25,7 +27,7 @@ const createInMemoryPersistence = () => {
25
27
  }
26
28
  };
27
29
  };
28
- const DEFAULT_DATABASE = "lunora";
30
+ const DEFAULT_DATABASE = "lunora-outbox";
29
31
  const DEFAULT_STORE = "offline-mutations";
30
32
  const ID_INDEX = "by_id";
31
33
  const promisifyRequest = (request) => new Promise((resolve, reject) => {
@@ -39,7 +41,7 @@ const promisifyRequest = (request) => new Promise((resolve, reject) => {
39
41
  const createIndexedDbPersistence = (options = {}) => {
40
42
  const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
41
43
  if (!factory) {
42
- throw new Error("createIndexedDbPersistence: no IndexedDB available — pass `indexedDB` or use createInMemoryPersistence()");
44
+ throw new LunoraError("INTERNAL", "createIndexedDbPersistence: no IndexedDB available — pass `indexedDB` or use createInMemoryPersistence()");
43
45
  }
44
46
  const databaseName = options.databaseName ?? DEFAULT_DATABASE;
45
47
  const storeName = options.storeName ?? DEFAULT_STORE;
@@ -101,5 +103,17 @@ const createIndexedDbPersistence = (options = {}) => {
101
103
  }
102
104
  };
103
105
  };
106
+ const resolvePersistenceAdapter = (option, autoProbe = true) => {
107
+ if (option === false) {
108
+ return void 0;
109
+ }
110
+ if (option) {
111
+ return option;
112
+ }
113
+ if (!autoProbe || typeof indexedDB === "undefined") {
114
+ return void 0;
115
+ }
116
+ return createIndexedDbPersistence();
117
+ };
104
118
 
105
- export { createInMemoryPersistence, createIndexedDbPersistence };
119
+ export { createInMemoryPersistence, createIndexedDbPersistence, resolvePersistenceAdapter };
@@ -1,3 +1,5 @@
1
+ import { LunoraError } from '@lunora/errors';
2
+
1
3
  const queryCacheKey = (functionPath, argsKey, shardKey) => `${functionPath}::${argsKey}::${shardKey ?? ""}`;
2
4
  const DEFAULT_MAX_ENTRIES = 500;
3
5
  const createInMemoryQueryCache = (options = {}) => {
@@ -35,10 +37,10 @@ const createInMemoryQueryCache = (options = {}) => {
35
37
  }
36
38
  };
37
39
  };
38
- const DEFAULT_DATABASE = "lunora";
40
+ const DEFAULT_DATABASE = "lunora-query-cache";
39
41
  const DEFAULT_STORE = "query-cache";
40
42
  const TS_INDEX = "by_ts";
41
- const DATABASE_VERSION = 2;
43
+ const DATABASE_VERSION = 1;
42
44
  const promisifyRequest = (request) => new Promise((resolve, reject) => {
43
45
  request.addEventListener("success", () => {
44
46
  resolve(request.result);
@@ -50,7 +52,7 @@ const promisifyRequest = (request) => new Promise((resolve, reject) => {
50
52
  const createIndexedDbQueryCache = (options = {}) => {
51
53
  const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
52
54
  if (!factory) {
53
- throw new Error("createIndexedDbQueryCache: no IndexedDB available — pass `indexedDB` or use createInMemoryQueryCache()");
55
+ throw new LunoraError("INTERNAL", "createIndexedDbQueryCache: no IndexedDB available — pass `indexedDB` or use createInMemoryQueryCache()");
54
56
  }
55
57
  const databaseName = options.databaseName ?? DEFAULT_DATABASE;
56
58
  const storeName = options.storeName ?? DEFAULT_STORE;
@@ -134,5 +136,17 @@ const createIndexedDbQueryCache = (options = {}) => {
134
136
  }
135
137
  };
136
138
  };
139
+ const resolveQueryCacheAdapter = (option) => {
140
+ if (option === false) {
141
+ return void 0;
142
+ }
143
+ if (option) {
144
+ return option;
145
+ }
146
+ if (typeof indexedDB === "undefined") {
147
+ return void 0;
148
+ }
149
+ return createIndexedDbQueryCache();
150
+ };
137
151
 
138
- export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey };
152
+ export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey, resolveQueryCacheAdapter };
@@ -0,0 +1 @@
1
+ export { c as createLocalStore } from './local-store-BNgN3Dw3.mjs';
@@ -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 };
@@ -1,4 +1,4 @@
1
- import { LunoraClient } from './LunoraClient-UiULzH_1.mjs';
1
+ import { LunoraClient } from './LunoraClient-hrmLXEHd.mjs';
2
2
 
3
3
  const createServerClient = (options) => {
4
4
  const client = new LunoraClient({ fetch: options.fetch, url: options.url });
@@ -0,0 +1,111 @@
1
+ const foldOptimistic = (base, layers) => {
2
+ let value = base;
3
+ for (const layer of layers) {
4
+ try {
5
+ value = layer.transform(value);
6
+ } catch {
7
+ }
8
+ }
9
+ return value;
10
+ };
11
+ const notifySubscription = (state, value) => {
12
+ if (value === state.lastValue) {
13
+ return;
14
+ }
15
+ state.lastValue = value;
16
+ for (const callback of state.callbacks) {
17
+ try {
18
+ callback(value);
19
+ } catch {
20
+ }
21
+ }
22
+ };
23
+ const applyOptimisticLayer = (state, optimistic) => {
24
+ let next;
25
+ try {
26
+ next = optimistic(state.lastValue);
27
+ } catch {
28
+ return void 0;
29
+ }
30
+ const layer = { id: /* @__PURE__ */ Symbol("optimistic"), transform: optimistic };
31
+ state.optimisticLayers.push(layer);
32
+ notifySubscription(state, next);
33
+ const remove = () => {
34
+ const index = state.optimisticLayers.findIndex((entry) => entry.id === layer.id);
35
+ if (index === -1) {
36
+ return false;
37
+ }
38
+ state.optimisticLayers.splice(index, 1);
39
+ return true;
40
+ };
41
+ const refold = () => {
42
+ notifySubscription(state, foldOptimistic(state.serverBase, state.optimisticLayers));
43
+ };
44
+ return {
45
+ confirm: (commitCursor) => {
46
+ if (commitCursor === void 0) {
47
+ remove();
48
+ return;
49
+ }
50
+ layer.commitCursor = commitCursor;
51
+ if (state.serverCursor !== void 0 && state.serverCursor >= commitCursor && remove()) {
52
+ refold();
53
+ }
54
+ },
55
+ rollback: () => {
56
+ if (remove()) {
57
+ refold();
58
+ }
59
+ }
60
+ };
61
+ };
62
+ const dropConfirmedLayers = (state, cursor) => {
63
+ if (cursor === void 0 || state.optimisticLayers.length === 0) {
64
+ return false;
65
+ }
66
+ const before = state.optimisticLayers.length;
67
+ state.optimisticLayers = state.optimisticLayers.filter((layer) => layer.commitCursor === void 0 || layer.commitCursor > cursor);
68
+ return state.optimisticLayers.length !== before;
69
+ };
70
+
71
+ const createLocalStore = (subscriptions, shardKey, stableStringify) => {
72
+ const confirms = [];
73
+ const rollbacks = [];
74
+ const findState = (functionRef, argsKey) => {
75
+ for (const state of subscriptions.all()) {
76
+ if (state.fn.__lunoraRef === functionRef && state.shardKey === shardKey && state.argsKey === argsKey) {
77
+ return state;
78
+ }
79
+ }
80
+ return void 0;
81
+ };
82
+ const store = {
83
+ getAllQueries: (function_) => {
84
+ const matches = [];
85
+ for (const state of subscriptions.all()) {
86
+ if (state.fn.__lunoraRef === function_.__lunoraRef && state.shardKey === shardKey) {
87
+ matches.push({ args: state.args, value: state.lastValue });
88
+ }
89
+ }
90
+ return matches;
91
+ },
92
+ getQuery: (function_, args) => {
93
+ const state = findState(function_.__lunoraRef, stableStringify(args ?? {}));
94
+ return state?.lastValue;
95
+ },
96
+ setQuery: (function_, args, value) => {
97
+ const state = findState(function_.__lunoraRef, stableStringify(args ?? {}));
98
+ if (!state) {
99
+ return;
100
+ }
101
+ const handle = applyOptimisticLayer(state, () => value);
102
+ if (handle) {
103
+ confirms.push(handle.confirm);
104
+ rollbacks.push(handle.rollback);
105
+ }
106
+ }
107
+ };
108
+ return { confirms, rollbacks, store };
109
+ };
110
+
111
+ export { applyOptimisticLayer as a, createLocalStore as c, dropConfirmedLayers as d, foldOptimistic as f, notifySubscription as n };