@doync/client 0.1.0 → 0.1.1
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/README.md +1 -17
- package/dist/adapter.cjs +1 -1
- package/dist/adapter.d.cts +1 -1
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.js +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/client-Bv6QMenB.cjs +15 -0
- package/dist/client-Db0Jfwuy.js +16 -0
- package/dist/client-Db0Jfwuy.js.map +1 -0
- package/dist/{client-CNyLMCw0.d.ts → client-OAVaC3pt.d.ts} +79 -91
- package/dist/client-OAVaC3pt.d.ts.map +1 -0
- package/dist/{client-DHXO0dbf.d.cts → client-OPt8Axyp.d.cts} +79 -91
- package/dist/client-OPt8Axyp.d.cts.map +1 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/internal.cjs +1 -1
- package/dist/internal.d.cts +3 -12
- package/dist/internal.d.cts.map +1 -1
- package/dist/internal.d.ts +3 -12
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/package.json +3 -3
- package/src/client.ts +82 -32
- package/src/engine.ts +188 -134
- package/src/index.ts +1 -6
- package/src/internal.ts +4 -4
- package/src/migrate.ts +1 -1
- package/src/replica/db/0002_prefs_table.sql +9 -0
- package/src/replica/db/meta/0002_snapshot.json +191 -0
- package/src/replica/db/meta/_journal.json +7 -0
- package/src/replica/db/schema.ts +12 -3
- package/src/replica/index.ts +5 -4
- package/src/replica/meta.ts +23 -0
- package/src/replica/track.ts +20 -39
- package/src/socket-reconnect.ts +29 -5
- package/dist/client-C6jAdhbe.cjs +0 -15
- package/dist/client-CNyLMCw0.d.ts.map +0 -1
- package/dist/client-ClV8ce6X.js +0 -16
- package/dist/client-ClV8ce6X.js.map +0 -1
- package/dist/client-DHXO0dbf.d.cts.map +0 -1
- package/src/client-mutation-registry.ts +0 -31
- package/src/mutations.ts +0 -96
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { _ as SchemaEvent, b as View, c as DoyncClient, d as MutationOptions, f as MutationResult, g as QueryStatus, h as PreloadOptions, l as FalsyQuery, m as PreloadHandle, p as OnceView, s as ConnectionStatus, u as LogoutBehavior, v as SchemaEventKind, x as ViewStatus, y as SubscribeOptions } from "./client-OPt8Axyp.cjs";
|
|
2
|
+
import { AuthData } from "@doync/core";
|
|
3
|
+
export type { AuthData, ConnectionStatus, DoyncClient, FalsyQuery, LogoutBehavior, MutationOptions, MutationResult, OnceView, PreloadHandle, PreloadOptions, QueryStatus, SchemaEvent, SchemaEventKind, SubscribeOptions, View, ViewStatus };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { _ as SchemaEvent, b as View, c as DoyncClient, d as MutationOptions, f as MutationResult, g as QueryStatus, h as PreloadOptions, l as FalsyQuery, m as PreloadHandle, p as OnceView, s as ConnectionStatus, u as LogoutBehavior, v as SchemaEventKind, x as ViewStatus, y as SubscribeOptions } from "./client-OAVaC3pt.js";
|
|
2
|
+
import { AuthData } from "@doync/core";
|
|
3
|
+
export type { AuthData, ConnectionStatus, DoyncClient, FalsyQuery, LogoutBehavior, MutationOptions, MutationResult, OnceView, PreloadHandle, PreloadOptions, QueryStatus, SchemaEvent, SchemaEventKind, SubscribeOptions, View, ViewStatus };
|
package/dist/internal.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./client-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./client-Bv6QMenB.cjs");let t=require("@doync/sqlite-parser");function n(e){return encodeURIComponent(e).replaceAll(`_`,`%5F`)}function r(e,t){let r=n(e);return t===null?`doync__${r}__anon.db`:`doync__${r}__${n(t)}.db`}function i(e){let n;try{n=(0,t.parse)(e)}catch(t){return console.warn(`extractWriteTable: failed to parse SQL statement`,{sql:e,err:t}),null}switch(n.kind){case`STMT_INSERT`:case`STMT_UPDATE`:case`STMT_DELETE`:return n.table??null;default:return null}}exports.ClientEngine=e.i,exports.__CONNECTED_CLOCK_META_KEY=e.a,exports.__LOGOUT_BEHAVIOR_PREF_KEY=e.o,exports.applyBundledMigrations=e.u,exports.bundledSchemaDdl=e.v,exports.classifyClientStatement=e.y,exports.createClientEngine=e.n,exports.createEngineTables=e.d,exports.dbFileForUserId=r,exports.dropConsumerTables=e.f,exports.extractWriteTable=i,exports.isFalsyQuery=e.s,exports.normalizeQuerySurface=e.c,exports.readMeta=e.m,exports.readPref=e.h,exports.replayMigrations=e.p,exports.resolveClientAuthData=e.r,exports.settledRejection=e.l,exports.splitClientStatements=e.b,exports.writeMeta=e.g,exports.writePref=e._;
|
package/dist/internal.d.cts
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import { DoyncSchema
|
|
1
|
+
import { A as replayMigrations, B as extractWriteTable, C as __LOGOUT_BEHAVIOR_PREF_KEY, D as applyBundledMigrations, E as settledRejection, M as readPref, N as writeMeta, O as createEngineTables, P as writePref, S as __CONNECTED_CLOCK_META_KEY, T as normalizeQuerySurface, a as ClientEngine, i as resolveClientAuthData, j as readMeta, k as dropConsumerTables, o as ClientEngineConfig, r as createClientEngine, w as isFalsyQuery } from "./client-OPt8Axyp.cjs";
|
|
2
|
+
import { DoyncSchema } from "@doync/core";
|
|
3
3
|
|
|
4
|
-
//#region src/client-mutation-registry.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* Flat `dottedName → {args, handler}` registry the client engine resolves
|
|
7
|
-
* optimistic bodies against (ADR-0019). Feed the SHARED tree so no `.server.ts`
|
|
8
|
-
* override enters the client bundle. Handler may return a promise (exclusive
|
|
9
|
-
* chain awaits); engine validates args at `mutate()` via carried schema.
|
|
10
|
-
*/
|
|
11
|
-
declare function toClientMutationRegistry(tree: MutationTree): ClientMutationRegistry;
|
|
12
|
-
//#endregion
|
|
13
4
|
//#region src/identity.d.ts
|
|
14
5
|
/**
|
|
15
6
|
* Durable replica file for one `(Database name, asserted userId)` pair:
|
|
@@ -65,5 +56,5 @@ declare function classifyClientStatement(statement: string): ClientStatementKind
|
|
|
65
56
|
*/
|
|
66
57
|
declare function bundledSchemaDdl(schema: DoyncSchema, fromVersion: number, toVersion: number): string[];
|
|
67
58
|
//#endregion
|
|
68
|
-
export { ClientEngine, type ClientEngineConfig, type ClientStatementKind, __CONNECTED_CLOCK_META_KEY,
|
|
59
|
+
export { ClientEngine, type ClientEngineConfig, type ClientStatementKind, __CONNECTED_CLOCK_META_KEY, __LOGOUT_BEHAVIOR_PREF_KEY, applyBundledMigrations, bundledSchemaDdl, classifyClientStatement, createClientEngine, createEngineTables, dbFileForUserId, dropConsumerTables, extractWriteTable, isFalsyQuery, normalizeQuerySurface, readMeta, readPref, replayMigrations, resolveClientAuthData, settledRejection, splitClientStatements, writeMeta, writePref };
|
|
69
60
|
//# sourceMappingURL=internal.d.cts.map
|
package/dist/internal.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.cts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"internal.d.cts","names":[],"sources":["../src/identity.ts","../src/migrate.ts"],"mappings":";;;;;;;;AAmCA;;;;iBAAgB,eAAA,CAAgB,IAAA,UAAc,MAAA;;;;;;AAA9C;;;;AAA8C;AAAA,KChBlC,mBAAA;;;AAAZ;;;;AAAY;AAgFZ;;;;AAAsC;iBAAtB,qBAAA,CAAsB,GAAA;;;;AAoBnC;AAeH;;;;iBAjBgB,uBAAA,CACd,SAAA,WACC,mBAAA;;;;;AAkBD;;;;;;iBAHc,gBAAA,CACd,MAAA,EAAQ,WAAA,EACR,WAAA,UACA,SAAA"}
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import { DoyncSchema
|
|
1
|
+
import { A as replayMigrations, B as extractWriteTable, C as __LOGOUT_BEHAVIOR_PREF_KEY, D as applyBundledMigrations, E as settledRejection, M as readPref, N as writeMeta, O as createEngineTables, P as writePref, S as __CONNECTED_CLOCK_META_KEY, T as normalizeQuerySurface, a as ClientEngine, i as resolveClientAuthData, j as readMeta, k as dropConsumerTables, o as ClientEngineConfig, r as createClientEngine, w as isFalsyQuery } from "./client-OAVaC3pt.js";
|
|
2
|
+
import { DoyncSchema } from "@doync/core";
|
|
3
3
|
|
|
4
|
-
//#region src/client-mutation-registry.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* Flat `dottedName → {args, handler}` registry the client engine resolves
|
|
7
|
-
* optimistic bodies against (ADR-0019). Feed the SHARED tree so no `.server.ts`
|
|
8
|
-
* override enters the client bundle. Handler may return a promise (exclusive
|
|
9
|
-
* chain awaits); engine validates args at `mutate()` via carried schema.
|
|
10
|
-
*/
|
|
11
|
-
declare function toClientMutationRegistry(tree: MutationTree): ClientMutationRegistry;
|
|
12
|
-
//#endregion
|
|
13
4
|
//#region src/identity.d.ts
|
|
14
5
|
/**
|
|
15
6
|
* Durable replica file for one `(Database name, asserted userId)` pair:
|
|
@@ -65,5 +56,5 @@ declare function classifyClientStatement(statement: string): ClientStatementKind
|
|
|
65
56
|
*/
|
|
66
57
|
declare function bundledSchemaDdl(schema: DoyncSchema, fromVersion: number, toVersion: number): string[];
|
|
67
58
|
//#endregion
|
|
68
|
-
export { ClientEngine, type ClientEngineConfig, type ClientStatementKind, __CONNECTED_CLOCK_META_KEY,
|
|
59
|
+
export { ClientEngine, type ClientEngineConfig, type ClientStatementKind, __CONNECTED_CLOCK_META_KEY, __LOGOUT_BEHAVIOR_PREF_KEY, applyBundledMigrations, bundledSchemaDdl, classifyClientStatement, createClientEngine, createEngineTables, dbFileForUserId, dropConsumerTables, extractWriteTable, isFalsyQuery, normalizeQuerySurface, readMeta, readPref, replayMigrations, resolveClientAuthData, settledRejection, splitClientStatements, writeMeta, writePref };
|
|
69
60
|
//# sourceMappingURL=internal.d.ts.map
|
package/dist/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"internal.d.ts","names":[],"sources":["../src/identity.ts","../src/migrate.ts"],"mappings":";;;;;;;;AAmCA;;;;iBAAgB,eAAA,CAAgB,IAAA,UAAc,MAAA;;;;;;AAA9C;;;;AAA8C;AAAA,KChBlC,mBAAA;;;AAAZ;;;;AAAY;AAgFZ;;;;AAAsC;iBAAtB,qBAAA,CAAsB,GAAA;;;;AAoBnC;AAeH;;;;iBAjBgB,uBAAA,CACd,SAAA,WACC,mBAAA;;;;;AAkBD;;;;;;iBAHc,gBAAA,CACd,MAAA,EAAQ,WAAA,EACR,WAAA,UACA,SAAA"}
|
package/dist/internal.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{_ as e,a as t,b as n,c as r,d as i,f as a,g as o,h as s,i as c,l,m as u,n as d,o as f,p,r as m,s as h,u as g,v as _,y as v}from"./client-
|
|
1
|
+
import{_ as e,a as t,b as n,c as r,d as i,f as a,g as o,h as s,i as c,l,m as u,n as d,o as f,p,r as m,s as h,u as g,v as _,y as v}from"./client-Db0Jfwuy.js";import{parse as y}from"@doync/sqlite-parser";function b(e){return encodeURIComponent(e).replaceAll(`_`,`%5F`)}function x(e,t){let n=b(e);return t===null?`doync__${n}__anon.db`:`doync__${n}__${b(t)}.db`}function S(e){let t;try{t=y(e)}catch(t){return console.warn(`extractWriteTable: failed to parse SQL statement`,{sql:e,err:t}),null}switch(t.kind){case`STMT_INSERT`:case`STMT_UPDATE`:case`STMT_DELETE`:return t.table??null;default:return null}}export{c as ClientEngine,t as __CONNECTED_CLOCK_META_KEY,f as __LOGOUT_BEHAVIOR_PREF_KEY,g as applyBundledMigrations,_ as bundledSchemaDdl,v as classifyClientStatement,d as createClientEngine,i as createEngineTables,x as dbFileForUserId,a as dropConsumerTables,S as extractWriteTable,h as isFalsyQuery,r as normalizeQuerySurface,u as readMeta,s as readPref,p as replayMigrations,m as resolveClientAuthData,l as settledRejection,n as splitClientStatements,o as writeMeta,e as writePref};
|
|
2
2
|
//# sourceMappingURL=internal.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doync/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "doync client engine: optimistic Layer-1 savepoint/rebase over a synchronous local-DB port",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"client",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@doync/core": "0.1.
|
|
60
|
+
"@doync/core": "0.1.1",
|
|
61
61
|
"@doync/sqlite-parser": "0.3053001.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"typescript": "^7.0.2",
|
|
70
70
|
"unplugin-raw": "^0.7.0",
|
|
71
71
|
"vitest": "4.1.9",
|
|
72
|
-
"@doync/drizzle": "0.1.
|
|
72
|
+
"@doync/drizzle": "0.1.1"
|
|
73
73
|
},
|
|
74
74
|
"scripts": {
|
|
75
75
|
"build": "rm -rf dist && tsdown",
|
package/src/client.ts
CHANGED
|
@@ -1,25 +1,32 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AuthContext,
|
|
3
|
+
AuthData,
|
|
4
|
+
DoyncSchema,
|
|
5
|
+
MutationTree,
|
|
6
|
+
} from '@doync/core'
|
|
7
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
8
|
+
|
|
9
|
+
import { flattenMutations, validateStandardSchema } from '@doync/core/internal'
|
|
2
10
|
|
|
3
11
|
import type { DoyncClient, LogoutBehavior, SchemaEvent } from './engine'
|
|
4
12
|
import type { LocalDb } from './port'
|
|
5
13
|
import type { SyncSocket } from './socket'
|
|
6
14
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { createEngineTables, writeMeta } from './replica'
|
|
15
|
+
import { __LOGOUT_BEHAVIOR_PREF_KEY, ClientEngine } from './engine'
|
|
16
|
+
import { createEngineTables, writePref } from './replica'
|
|
10
17
|
|
|
11
18
|
// The durable logout-policy seam (ADR-0022) is owned by the engine (the layer
|
|
12
|
-
// that owns `
|
|
13
|
-
// Only LogoutBehavior is public; the
|
|
19
|
+
// that owns `__doync_prefs` and the runtime {@link ClientEngine.setLogoutBehavior}).
|
|
20
|
+
// Only LogoutBehavior is public; the pref key stays on `./internal`.
|
|
14
21
|
export type { LogoutBehavior } from './engine'
|
|
15
22
|
|
|
16
|
-
// Identity is the asserted triple `{ token, ctx, userId }` — never derived
|
|
17
|
-
// from a bearer token (ADR-0018 asserted-identity).
|
|
18
23
|
/**
|
|
19
24
|
* Options for {@link createClient}. Platform adapters (`@doync/web`,
|
|
20
25
|
* `@doync/mobile`) fill these; app code rarely calls `createClient` directly.
|
|
21
26
|
*/
|
|
22
|
-
export interface CreateClientOptions<
|
|
27
|
+
export interface CreateClientOptions<
|
|
28
|
+
TAuthContext extends AuthContext = AuthContext,
|
|
29
|
+
> {
|
|
23
30
|
/** Synchronous local SQLite port (wa-sqlite / node:sqlite / op-sqlite). */
|
|
24
31
|
readonly db: LocalDb
|
|
25
32
|
/** Synced schema shared with Origin and Mirror. */
|
|
@@ -32,22 +39,16 @@ export interface CreateClientOptions<TAuthData = unknown> {
|
|
|
32
39
|
/** Transport to the Mirror. */
|
|
33
40
|
readonly socket: SyncSocket
|
|
34
41
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*/
|
|
38
|
-
readonly token?: string
|
|
39
|
-
/**
|
|
40
|
-
* Projected auth context for optimistic query/mutation resolution (mirror
|
|
41
|
-
* your server `toContext`). Defaults to `{}`.
|
|
42
|
+
* Whole client identity, or `null` for anonymous. `token` is optional inside
|
|
43
|
+
* {@link AuthData} (cookie auth); `ctx` is required when authenticated.
|
|
42
44
|
*/
|
|
43
|
-
readonly
|
|
45
|
+
readonly authData: AuthData<TAuthContext> | null
|
|
44
46
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
+
* Standard Schema for `authData.ctx`. When present, construction validates
|
|
48
|
+
* synchronously and throws on failure. Platform adapters pass the consumer's
|
|
49
|
+
* shared `ctxValidationSchema`.
|
|
47
50
|
*/
|
|
48
|
-
readonly
|
|
49
|
-
/** Pin a durable client id across restarts. */
|
|
50
|
-
readonly clientId?: string
|
|
51
|
+
readonly ctxValidationSchema: StandardSchemaV1<unknown, TAuthContext>
|
|
51
52
|
/** Observe schema/recovery transitions. */
|
|
52
53
|
readonly onSchemaEvent?: (event: SchemaEvent) => void
|
|
53
54
|
/**
|
|
@@ -63,38 +64,87 @@ export interface CreateClientOptions<TAuthData = unknown> {
|
|
|
63
64
|
* Mirror socket. App code normally goes through `@doync/web` / `@doync/mobile`
|
|
64
65
|
* instead.
|
|
65
66
|
*/
|
|
66
|
-
export function createClient<
|
|
67
|
-
options: CreateClientOptions<
|
|
67
|
+
export function createClient<TAuthContext extends AuthContext = AuthContext>(
|
|
68
|
+
options: CreateClientOptions<TAuthContext>,
|
|
68
69
|
): DoyncClient {
|
|
69
70
|
return createClientEngine(options)
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* {@link CreateClientOptions} for trusted internal construction: the web DB
|
|
75
|
+
* worker receives tab-validated identity over the wire and cannot hold the
|
|
76
|
+
* consumer's schema (a validator is a function), so the schema is optional here
|
|
77
|
+
* — absent means the caller already validated.
|
|
78
|
+
*/
|
|
79
|
+
export type CreateClientEngineOptions<
|
|
80
|
+
TAuthContext extends AuthContext = AuthContext,
|
|
81
|
+
> = Omit<CreateClientOptions<TAuthContext>, 'ctxValidationSchema'> & {
|
|
82
|
+
readonly ctxValidationSchema?: StandardSchemaV1<unknown, TAuthContext>
|
|
83
|
+
/** Pin a durable client id (monorepo test/bench lanes only). */
|
|
84
|
+
readonly clientId?: string
|
|
85
|
+
}
|
|
86
|
+
|
|
72
87
|
/**
|
|
73
88
|
* Concrete-engine factory (ADR-0033 / closeio/doync#241). Same construction as
|
|
74
89
|
* {@link createClient}, but typed as {@link ClientEngine} so platform adapters
|
|
75
90
|
* (web DB-worker, mobile wrapper) can reach engine-only fields like `clientId`
|
|
76
91
|
* without an unchecked downcast. Exported on `@doync/client/internal` only.
|
|
77
92
|
*/
|
|
78
|
-
export function createClientEngine<
|
|
79
|
-
|
|
80
|
-
): ClientEngine {
|
|
93
|
+
export function createClientEngine<
|
|
94
|
+
TAuthContext extends AuthContext = AuthContext,
|
|
95
|
+
>(options: CreateClientEngineOptions<TAuthContext>): ClientEngine {
|
|
81
96
|
// Logout policy must land before boot (ADR-0022 / #135): construction opens
|
|
82
97
|
// the optimistic overlay (ADR-0019), so a later write on this connection would
|
|
83
98
|
// join the savepoint and roll back. Pre-boot is autocommit.
|
|
84
99
|
if (options.logoutBehavior !== undefined) {
|
|
85
100
|
createEngineTables(options.db)
|
|
86
|
-
|
|
101
|
+
writePref(options.db, __LOGOUT_BEHAVIOR_PREF_KEY, options.logoutBehavior)
|
|
87
102
|
}
|
|
103
|
+
const identity = resolveClientAuthData(
|
|
104
|
+
options.authData,
|
|
105
|
+
options.ctxValidationSchema,
|
|
106
|
+
)
|
|
88
107
|
return new ClientEngine({
|
|
89
108
|
db: options.db,
|
|
90
109
|
schema: options.schema,
|
|
91
|
-
mutations:
|
|
110
|
+
mutations: flattenMutations(options.mutations),
|
|
92
111
|
socket: options.socket,
|
|
93
112
|
// Asserted identity (ADR-0018 / #167): never derived.
|
|
94
|
-
ctx:
|
|
95
|
-
token:
|
|
96
|
-
userId:
|
|
113
|
+
ctx: identity.ctx,
|
|
114
|
+
token: identity.token,
|
|
115
|
+
userId: identity.userId,
|
|
97
116
|
clientId: options.clientId,
|
|
98
117
|
onSchemaEvent: options.onSchemaEvent,
|
|
99
118
|
})
|
|
100
119
|
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Validate and flatten `authData` for engine slots. When a schema is present
|
|
123
|
+
* and identity is non-null, `ctx` is validated synchronously (throws at the
|
|
124
|
+
* call site). Anonymous (`null`) yields `userId: null`, `ctx: null`, no token.
|
|
125
|
+
*/
|
|
126
|
+
export function resolveClientAuthData<TAuthContext extends AuthContext>(
|
|
127
|
+
authData: AuthData<TAuthContext> | null,
|
|
128
|
+
ctxValidationSchema?: StandardSchemaV1<unknown, TAuthContext>,
|
|
129
|
+
): {
|
|
130
|
+
userId: string | null
|
|
131
|
+
token: string | undefined
|
|
132
|
+
ctx: AuthContext
|
|
133
|
+
} {
|
|
134
|
+
if (authData === null) {
|
|
135
|
+
return { userId: null, token: undefined, ctx: null }
|
|
136
|
+
}
|
|
137
|
+
let ctx: Record<string, unknown> = authData.ctx
|
|
138
|
+
if (ctxValidationSchema !== undefined) {
|
|
139
|
+
ctx = validateStandardSchema(
|
|
140
|
+
ctxValidationSchema,
|
|
141
|
+
authData.ctx,
|
|
142
|
+
'auth context',
|
|
143
|
+
) as Record<string, unknown>
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
userId: authData.userId,
|
|
147
|
+
token: authData.token,
|
|
148
|
+
ctx,
|
|
149
|
+
}
|
|
150
|
+
}
|