@lunora/client 1.0.0-alpha.11 → 1.0.0-alpha.110
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 +16 -3
- package/dist/auth/index.d.mts +36 -12
- package/dist/auth/index.d.ts +36 -12
- package/dist/auth/index.mjs +1 -60
- package/dist/index.d.mts +884 -273
- package/dist/index.d.ts +884 -273
- package/dist/index.mjs +1 -15
- package/dist/packem_shared/CONFLICT_ERROR_CODE-BOeeP_Wl.mjs +1 -0
- package/dist/packem_shared/ClientServiceWorker-DXnBXeWK.mjs +1 -0
- package/dist/packem_shared/DEFAULT_MAX_BUFFER-D3QH2iaq.mjs +1 -0
- package/dist/packem_shared/LunoraClient-D4FH_fjY.mjs +1 -0
- package/dist/packem_shared/OfflineQueue-BuHVa8B0.mjs +1 -0
- package/dist/packem_shared/RETIRE_AFTER_DURABLE_SEQ_ADVANCE-DoEHtuR8.mjs +1 -0
- package/dist/packem_shared/SKIP-d7LeP-sY.mjs +1 -0
- package/dist/packem_shared/SubscriptionRegistry-CS-AFUI9.mjs +1 -0
- package/dist/packem_shared/TabCoordinator-CXD7vulJ.mjs +1 -0
- package/dist/packem_shared/anyApi-CBOws2ZA.mjs +1 -0
- package/dist/packem_shared/applyDelta-DwcQmRsV.mjs +1 -0
- package/dist/packem_shared/createAsyncStoragePersistence-CeUW9NTj.mjs +1 -0
- package/dist/packem_shared/createAsyncStorageQueryCache-BfZkthAE.mjs +1 -0
- package/dist/packem_shared/createCallRunner-Bwcrfh76.mjs +1 -0
- package/dist/packem_shared/createClientQuery-B8Nfj-7o.mjs +1 -0
- package/dist/packem_shared/createInMemoryBookmarkStorage-BooZhW0n.mjs +1 -0
- package/dist/packem_shared/createInMemoryPersistence-Cz2W6XVj.mjs +1 -0
- package/dist/packem_shared/createInMemoryQueryCache-D2uNHLfM.mjs +1 -0
- package/dist/packem_shared/createLocalStore-BFdXRTFz.mjs +1 -0
- package/dist/packem_shared/createMutatorRunner-CuMRJpUx.mjs +1 -0
- package/dist/packem_shared/createReconnect-CjTmjJDH.mjs +1 -0
- package/dist/packem_shared/createReply-CwFABEJs.mjs +1 -0
- package/dist/packem_shared/createServerClient-Chmnq4DL.mjs +1 -0
- package/dist/packem_shared/createSnapshotPrecondition-GRVKxPsh.mjs +1 -0
- package/dist/packem_shared/delta-merge-vxvH3PvF.mjs +1 -0
- package/dist/packem_shared/deserializePreloaded-C6NTQdFa.mjs +1 -0
- package/dist/packem_shared/function-reference.d-Br_hsKje.d.mts +45 -0
- package/dist/packem_shared/function-reference.d-Br_hsKje.d.ts +45 -0
- package/dist/packem_shared/getServerSession-BaOoo1p6.mjs +1 -0
- package/dist/packem_shared/httpStream-CPdblK2G.mjs +11 -0
- package/dist/packem_shared/idb-utility-C8WS390w.mjs +1 -0
- package/dist/packem_shared/local-store-BjenEm3t.mjs +1 -0
- package/dist/packem_shared/lunora-client.d-CGR-MObo.d.ts +4007 -0
- package/dist/packem_shared/lunora-client.d-qVBwKXE1.d.mts +4007 -0
- package/dist/packem_shared/offline-queue-DSCpAxOp.mjs +1 -0
- package/dist/packem_shared/preload.d-0j8xgrYf.d.mts +21 -0
- package/dist/packem_shared/preload.d-DTpiMCut.d.ts +21 -0
- package/dist/packem_shared/preloadQuery-uFy24PCR.mjs +1 -0
- package/dist/packem_shared/single-blob-store-DrhzObic.mjs +1 -0
- package/dist/packem_shared/wire-codec-Sw1rAu-Z.mjs +1 -0
- package/dist/packem_shared/wire-key-HsUDTlQ7.mjs +1 -0
- package/dist/pagination/index.d.mts +42 -42
- package/dist/pagination/index.d.ts +42 -42
- package/dist/pagination/index.mjs +1 -61
- package/dist/query/index.d.mts +111 -43
- package/dist/query/index.d.ts +111 -43
- package/dist/query/index.mjs +1 -1
- package/dist/service.d.mts +49 -0
- package/dist/service.d.ts +49 -0
- package/dist/service.mjs +1 -0
- package/dist/ssr/index.d.mts +109 -79
- package/dist/ssr/index.d.ts +109 -79
- package/dist/ssr/index.mjs +1 -4
- package/dist/upload.d.mts +35 -0
- package/dist/upload.d.ts +35 -0
- package/dist/upload.mjs +1 -0
- package/package.json +16 -1
- package/dist/packem_shared/CONFLICT_ERROR_CODE-aUdVbEDw.mjs +0 -4
- package/dist/packem_shared/DEFAULT_MAX_BUFFER-BDkqO5PW.mjs +0 -107
- package/dist/packem_shared/LunoraClient-6J-4BGWK.mjs +0 -2722
- package/dist/packem_shared/OfflineQueue-BI0FNNvc.mjs +0 -1
- package/dist/packem_shared/SKIP-vItZChkw.mjs +0 -50
- package/dist/packem_shared/SubscriptionRegistry-Dn-7k7eo.mjs +0 -1
- package/dist/packem_shared/applyDelta-4jFGTPA3.mjs +0 -61
- package/dist/packem_shared/createAsyncStoragePersistence-1Z5BZ8RC.mjs +0 -45
- package/dist/packem_shared/createInMemoryBookmarkStorage-BoN7a7TH.mjs +0 -11
- package/dist/packem_shared/createInMemoryPersistence-DlFjWtOm.mjs +0 -117
- package/dist/packem_shared/createInMemoryQueryCache-4AkTV38-.mjs +0 -150
- package/dist/packem_shared/createLocalStore-IOur0jHF.mjs +0 -1
- package/dist/packem_shared/createMutationRunner-BqsavzvG.mjs +0 -21
- package/dist/packem_shared/createMutatorRunner-BETvCd0p.mjs +0 -31
- package/dist/packem_shared/createReconnect-Di_-oHH7.mjs +0 -22
- package/dist/packem_shared/createServerClient-CtklXrs2.mjs +0 -11
- package/dist/packem_shared/deserializePreloaded-C0eJTY_W.mjs +0 -4
- package/dist/packem_shared/getServerSession-8jXewqxd.mjs +0 -13
- package/dist/packem_shared/local-store-BNgN3Dw3.mjs +0 -111
- package/dist/packem_shared/lunora-client.d-Dm1BYq19.d.mts +0 -2206
- package/dist/packem_shared/lunora-client.d-Dm1BYq19.d.ts +0 -2206
- package/dist/packem_shared/offline-queue-7Wc4onA0.mjs +0 -164
- package/dist/packem_shared/preload.d-BfWzGJWV.d.mts +0 -20
- package/dist/packem_shared/preload.d-Sp_Ef-_u.d.ts +0 -20
- package/dist/packem_shared/preloadQuery-lobFkD2Z.mjs +0 -13
- package/dist/packem_shared/subscription-C1Jy7HiF.mjs +0 -55
package/LICENSE.md
CHANGED
|
@@ -103,3 +103,9 @@ Unless required by applicable law or agreed to in writing, software distributed
|
|
|
103
103
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
104
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
105
|
specific language governing permissions and limitations under the License.
|
|
106
|
+
|
|
107
|
+
<!-- DEPENDENCIES -->
|
|
108
|
+
<!-- /DEPENDENCIES -->
|
|
109
|
+
|
|
110
|
+
<!-- TYPE_DEPENDENCIES -->
|
|
111
|
+
<!-- /TYPE_DEPENDENCIES -->
|
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
-
The framework-agnostic browser/edge SDK for Lunora. It runs RPC over HTTP and real-time deltas over a single multiplexed WebSocket, with optimistic updates, an offline mutation queue, and
|
|
37
|
+
The framework-agnostic browser/edge SDK for Lunora. It runs RPC over HTTP and real-time deltas over a single multiplexed WebSocket, with optimistic updates, an offline mutation queue, and exponential-backoff-with-jitter reconnect built in. It is the lowest-level user-facing entry point that every framework adapter (React, Vue, Svelte, Solid) layers on top of.
|
|
38
38
|
|
|
39
39
|
Part of the [Lunora](https://github.com/anolilab/lunora) framework — a type-safe, real-time backend on Cloudflare Workers + Durable Objects with a Vite-first DX.
|
|
40
40
|
|
|
@@ -63,8 +63,21 @@ const client = new LunoraClient({ url: "https://app.acme.test" });
|
|
|
63
63
|
// One-shot query (HTTP, carries the D1 bookmark for read-your-writes).
|
|
64
64
|
const messages = await client.query(api.messages.list, { room: "general" });
|
|
65
65
|
|
|
66
|
-
// Mutation with an optimistic update
|
|
67
|
-
|
|
66
|
+
// Mutation with an optimistic update. `optimisticUpdate` names the query it
|
|
67
|
+
// patches — a write and the queries it affects are different functions, and only
|
|
68
|
+
// you know which. (The per-call `optimistic` shortcut patches the subscription
|
|
69
|
+
// registered under the mutation's OWN reference and args, nothing else.)
|
|
70
|
+
await client.mutation(
|
|
71
|
+
api.messages.send,
|
|
72
|
+
{ room: "general", body: "hi" },
|
|
73
|
+
{
|
|
74
|
+
optimisticUpdate: (store, args) => {
|
|
75
|
+
const current = store.getQuery(api.messages.list, { room: args.room }) ?? [];
|
|
76
|
+
|
|
77
|
+
store.setQuery(api.messages.list, { room: args.room }, [...current, { body: args.body, pending: true }]);
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
);
|
|
68
81
|
|
|
69
82
|
// Live subscription over WS — returns an unsubscribe function.
|
|
70
83
|
const unsubscribe = client.subscribe(api.messages.list, { room: "general" }, (next) => {
|
package/dist/auth/index.d.mts
CHANGED
|
@@ -1,20 +1,44 @@
|
|
|
1
|
-
import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-qVBwKXE1.mjs";
|
|
2
|
+
import '@lunora/errors';
|
|
3
|
+
import "../packem_shared/function-reference.d-Br_hsKje.mjs";
|
|
2
4
|
import '@lunora/runtime';
|
|
5
|
+
/**
|
|
6
|
+
* Resolved authentication state. See the contract table in this module's header
|
|
7
|
+
* — the states are not interchangeable, and `unreachable` is the one that exists
|
|
8
|
+
* only so "the server said no session" and "we could not ask" stop colliding.
|
|
9
|
+
*/
|
|
10
|
+
type AuthStatus = "authenticated" | "loading" | "unauthenticated" | "unreachable";
|
|
11
|
+
/**
|
|
12
|
+
* Whether a gate should render its authenticated branch.
|
|
13
|
+
*
|
|
14
|
+
* Both `authenticated` and `unreachable` qualify: the credential is held in
|
|
15
|
+
* either case, and only the identity round-trip differs.
|
|
16
|
+
*/
|
|
17
|
+
declare const isAuthenticatedStatus: (status: AuthStatus) => boolean;
|
|
18
|
+
/** Whether a gate should render its loading branch — the first resolve only. */
|
|
19
|
+
declare const isLoadingStatus: (status: AuthStatus) => boolean;
|
|
3
20
|
interface IdentityStore {
|
|
4
|
-
/**
|
|
21
|
+
/** The current {@link AuthStatus} — what a gate branches on. */
|
|
22
|
+
getStatus: () => AuthStatus;
|
|
23
|
+
/**
|
|
24
|
+
* The last resolved user, or `null`. `null` does NOT mean signed out on its
|
|
25
|
+
* own: read `getStatus` for that. A user resolved before the endpoint
|
|
26
|
+
* went unreachable is retained, so the UI keeps rendering the identity it
|
|
27
|
+
* last knew instead of blanking.
|
|
28
|
+
*/
|
|
5
29
|
getUser: () => User | null;
|
|
6
30
|
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
31
|
+
* Subscribe to identity changes. `onChange` is called whenever the user or
|
|
32
|
+
* the status changes. Returns an unsubscribe handle.
|
|
33
|
+
*/
|
|
10
34
|
subscribe: (onChange: () => void) => () => void;
|
|
11
35
|
}
|
|
12
36
|
/**
|
|
13
|
-
* Return the per-client identity store, creating it on first access.
|
|
14
|
-
*
|
|
15
|
-
* The store is cached via a `WeakMap` so it is GC'd when the client is dropped,
|
|
16
|
-
* and creation is idempotent — calling this multiple times with the same client
|
|
17
|
-
* returns the same store, keeping the single-fetch / fan-out invariant.
|
|
18
|
-
*/
|
|
37
|
+
* Return the per-client identity store, creating it on first access.
|
|
38
|
+
*
|
|
39
|
+
* The store is cached via a `WeakMap` so it is GC'd when the client is dropped,
|
|
40
|
+
* and creation is idempotent — calling this multiple times with the same client
|
|
41
|
+
* returns the same store, keeping the single-fetch / fan-out invariant.
|
|
42
|
+
*/
|
|
19
43
|
declare const getIdentityStore: (client: LunoraClient) => IdentityStore;
|
|
20
|
-
export { type IdentityStore, getIdentityStore };
|
|
44
|
+
export { type AuthStatus, type IdentityStore, getIdentityStore, isAuthenticatedStatus, isLoadingStatus };
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,20 +1,44 @@
|
|
|
1
|
-
import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-CGR-MObo.js";
|
|
2
|
+
import '@lunora/errors';
|
|
3
|
+
import "../packem_shared/function-reference.d-Br_hsKje.js";
|
|
2
4
|
import '@lunora/runtime';
|
|
5
|
+
/**
|
|
6
|
+
* Resolved authentication state. See the contract table in this module's header
|
|
7
|
+
* — the states are not interchangeable, and `unreachable` is the one that exists
|
|
8
|
+
* only so "the server said no session" and "we could not ask" stop colliding.
|
|
9
|
+
*/
|
|
10
|
+
type AuthStatus = "authenticated" | "loading" | "unauthenticated" | "unreachable";
|
|
11
|
+
/**
|
|
12
|
+
* Whether a gate should render its authenticated branch.
|
|
13
|
+
*
|
|
14
|
+
* Both `authenticated` and `unreachable` qualify: the credential is held in
|
|
15
|
+
* either case, and only the identity round-trip differs.
|
|
16
|
+
*/
|
|
17
|
+
declare const isAuthenticatedStatus: (status: AuthStatus) => boolean;
|
|
18
|
+
/** Whether a gate should render its loading branch — the first resolve only. */
|
|
19
|
+
declare const isLoadingStatus: (status: AuthStatus) => boolean;
|
|
3
20
|
interface IdentityStore {
|
|
4
|
-
/**
|
|
21
|
+
/** The current {@link AuthStatus} — what a gate branches on. */
|
|
22
|
+
getStatus: () => AuthStatus;
|
|
23
|
+
/**
|
|
24
|
+
* The last resolved user, or `null`. `null` does NOT mean signed out on its
|
|
25
|
+
* own: read `getStatus` for that. A user resolved before the endpoint
|
|
26
|
+
* went unreachable is retained, so the UI keeps rendering the identity it
|
|
27
|
+
* last knew instead of blanking.
|
|
28
|
+
*/
|
|
5
29
|
getUser: () => User | null;
|
|
6
30
|
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
31
|
+
* Subscribe to identity changes. `onChange` is called whenever the user or
|
|
32
|
+
* the status changes. Returns an unsubscribe handle.
|
|
33
|
+
*/
|
|
10
34
|
subscribe: (onChange: () => void) => () => void;
|
|
11
35
|
}
|
|
12
36
|
/**
|
|
13
|
-
* Return the per-client identity store, creating it on first access.
|
|
14
|
-
*
|
|
15
|
-
* The store is cached via a `WeakMap` so it is GC'd when the client is dropped,
|
|
16
|
-
* and creation is idempotent — calling this multiple times with the same client
|
|
17
|
-
* returns the same store, keeping the single-fetch / fan-out invariant.
|
|
18
|
-
*/
|
|
37
|
+
* Return the per-client identity store, creating it on first access.
|
|
38
|
+
*
|
|
39
|
+
* The store is cached via a `WeakMap` so it is GC'd when the client is dropped,
|
|
40
|
+
* and creation is idempotent — calling this multiple times with the same client
|
|
41
|
+
* returns the same store, keeping the single-fetch / fan-out invariant.
|
|
42
|
+
*/
|
|
19
43
|
declare const getIdentityStore: (client: LunoraClient) => IdentityStore;
|
|
20
|
-
export { type IdentityStore, getIdentityStore };
|
|
44
|
+
export { type AuthStatus, type IdentityStore, getIdentityStore, isAuthenticatedStatus, isLoadingStatus };
|
package/dist/auth/index.mjs
CHANGED
|
@@ -1,60 +1 @@
|
|
|
1
|
-
const
|
|
2
|
-
const createIdentityStore = (client) => {
|
|
3
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
4
|
-
let user = null;
|
|
5
|
-
let started = false;
|
|
6
|
-
const notify = () => {
|
|
7
|
-
for (const listener of listeners) {
|
|
8
|
-
listener();
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
let generation = 0;
|
|
12
|
-
const setUser = (next) => {
|
|
13
|
-
if (user !== next) {
|
|
14
|
-
user = next;
|
|
15
|
-
notify();
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
const refresh = () => {
|
|
19
|
-
generation += 1;
|
|
20
|
-
const current = generation;
|
|
21
|
-
if (client.getAuthToken() === null) {
|
|
22
|
-
setUser(null);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
client.getCurrentUser().then((next) => {
|
|
26
|
-
if (current === generation) {
|
|
27
|
-
setUser(next);
|
|
28
|
-
}
|
|
29
|
-
return void 0;
|
|
30
|
-
}).catch(() => {
|
|
31
|
-
if (current === generation) {
|
|
32
|
-
setUser(null);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
};
|
|
36
|
-
client.onAuthTokenChange(refresh);
|
|
37
|
-
return {
|
|
38
|
-
getUser: () => user,
|
|
39
|
-
subscribe: (onChange) => {
|
|
40
|
-
listeners.add(onChange);
|
|
41
|
-
if (!started) {
|
|
42
|
-
started = true;
|
|
43
|
-
refresh();
|
|
44
|
-
}
|
|
45
|
-
return () => {
|
|
46
|
-
listeners.delete(onChange);
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
const getIdentityStore = (client) => {
|
|
52
|
-
let store = stores.get(client);
|
|
53
|
-
if (!store) {
|
|
54
|
-
store = createIdentityStore(client);
|
|
55
|
-
stores.set(client, store);
|
|
56
|
-
}
|
|
57
|
-
return store;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export { getIdentityStore };
|
|
1
|
+
const f=t=>t==="authenticated"||t==="unreachable",g=t=>t==="loading",l=new WeakMap,h=t=>{const n=new Set;let a=null,r=t.getAuthToken()===null?"unauthenticated":"loading",i=!1;const d=()=>{for(const e of n)e()};let o=0;const s=(e,u)=>{(r!==e||a!==u)&&(r=e,a=u,d())},c=()=>{o+=1;const e=o;if(t.getAuthToken()===null){s("unauthenticated",null);return}s(a===null?"loading":"authenticated",a),t.getCurrentUser().then(u=>{e===o&&s(u===null?"unauthenticated":"authenticated",u)}).catch(()=>{e===o&&s("unreachable",a)})};return t.onAuthTokenChange(c),t.onConnectionStatus(e=>{e==="connected"&&r==="unreachable"&&c()}),{getStatus:()=>r,getUser:()=>a,subscribe:e=>(n.add(e),i||(i=!0,c()),()=>{n.delete(e)})}},S=t=>{let n=l.get(t);return n||(n=h(t),l.set(t,n)),n};export{S as getIdentityStore,f as isAuthenticatedStatus,g as isLoadingStatus};
|