@rocicorp/zero 1.4.0 → 1.5.0-canary.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/out/analyze-query/src/analyze-cli.js +2 -2
- package/out/analyze-query/src/analyze-cli.js.map +1 -1
- package/out/zero/package.js +1 -1
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/auth/auth.d.ts +1 -1
- package/out/zero-cache/src/auth/auth.d.ts.map +1 -1
- package/out/zero-cache/src/auth/auth.js +1 -1
- package/out/zero-cache/src/auth/auth.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +8 -0
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +8 -4
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +28 -6
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js +2 -2
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts +21 -7
- package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +26 -9
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +2 -1
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +5 -2
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/server/syncer.js +3 -3
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +2 -2
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +24 -20
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +258 -45
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +119 -83
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +2 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +1 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +3 -3
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/http-service.d.ts +1 -0
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +5 -4
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +1 -2
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +4 -3
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +57 -38
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js +2 -1
- package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts +41 -27
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js +147 -104
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +6 -0
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +8 -0
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +3 -3
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +119 -86
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/workers/connection.js +2 -2
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +7 -7
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +11 -10
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +15 -7
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/crud-impl.d.ts +1 -1
- package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
- package/out/zero-client/src/client/crud-impl.js +1 -1
- package/out/zero-client/src/client/crud-impl.js.map +1 -1
- package/out/zero-client/src/client/crud.d.ts +1 -1
- package/out/zero-client/src/client/crud.d.ts.map +1 -1
- package/out/zero-client/src/client/crud.js +1 -1
- package/out/zero-client/src/client/crud.js.map +1 -1
- package/out/zero-client/src/client/keys.d.ts +1 -1
- package/out/zero-client/src/client/keys.d.ts.map +1 -1
- package/out/zero-client/src/client/keys.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts +2 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.js +3 -3
- package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +2 -2
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/types/client-state.d.ts +1 -1
- package/out/zero-client/src/types/client-state.d.ts.map +1 -1
- package/out/zero-protocol/src/custom-queries.js +1 -1
- package/out/zero-protocol/src/down.js +1 -1
- package/out/zero-protocol/src/error-kind-enum.d.ts +1 -2
- package/out/zero-protocol/src/error-kind-enum.d.ts.map +1 -1
- package/out/zero-protocol/src/error-kind-enum.js.map +1 -1
- package/out/zero-protocol/src/mutate-server.d.ts +165 -0
- package/out/zero-protocol/src/mutate-server.d.ts.map +1 -0
- package/out/zero-protocol/src/mutate-server.js +24 -0
- package/out/zero-protocol/src/mutate-server.js.map +1 -0
- package/out/zero-protocol/src/mutation.d.ts +229 -0
- package/out/zero-protocol/src/mutation.d.ts.map +1 -0
- package/out/zero-protocol/src/mutation.js +112 -0
- package/out/zero-protocol/src/mutation.js.map +1 -0
- package/out/zero-protocol/src/mutations-patch.js +1 -1
- package/out/zero-protocol/src/mutations-patch.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +3 -234
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +3 -114
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-protocol/src/query-server.d.ts +150 -0
- package/out/zero-protocol/src/query-server.d.ts.map +1 -0
- package/out/zero-protocol/src/query-server.js +16 -0
- package/out/zero-protocol/src/query-server.js.map +1 -0
- package/out/zero-protocol/src/up.js +1 -1
- package/out/zero-server/src/mod.d.ts +4 -2
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +50 -4
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +73 -36
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.d.ts +3 -3
- package/out/zero-server/src/push-processor.d.ts.map +1 -1
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +45 -53
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +72 -53
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-types/src/default-types.d.ts +1 -0
- package/out/zero-types/src/default-types.d.ts.map +1 -1
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +17 -7
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/ivm/cap.d.ts +32 -0
- package/out/zql/src/ivm/cap.d.ts.map +1 -0
- package/out/zql/src/ivm/cap.js +205 -0
- package/out/zql/src/ivm/cap.js.map +1 -0
- package/out/zql/src/ivm/constraint.js +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +61 -15
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +3 -4
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/schema.d.ts +8 -0
- package/out/zql/src/ivm/schema.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +2 -2
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +11 -2
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/query/query-registry.d.ts +9 -2
- package/out/zql/src/query/query-registry.d.ts.map +1 -1
- package/out/zql/src/query/query-registry.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +4 -1
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,24 @@ import { type Auth, type ValidateLegacyJWT } from '../../auth/auth.ts';
|
|
|
5
5
|
import type { ZeroConfig } from '../../config/zero-config.ts';
|
|
6
6
|
import type { ConnectParams } from '../../workers/connect-params.ts';
|
|
7
7
|
export type ConnectionState = 'provisional' | 'validated';
|
|
8
|
+
/**
|
|
9
|
+
* Normalized user identity shared by live connection state and group auth state.
|
|
10
|
+
* `id: null` means logged out.
|
|
11
|
+
*/
|
|
12
|
+
export type UserState = {
|
|
13
|
+
readonly id: string | null;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Delineates the two paths for validating a connection: either server can validate
|
|
17
|
+
* the user's identity and return a definitive userID to trust, or we fall back to
|
|
18
|
+
* trusting the one provided by the client in the incoming query params.
|
|
19
|
+
*/
|
|
20
|
+
export type ConnectionValidation = {
|
|
21
|
+
kind: 'client-fallback';
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'server-validated';
|
|
24
|
+
validatedUserID: string | null;
|
|
25
|
+
};
|
|
8
26
|
/**
|
|
9
27
|
* Identifies one live websocket for a client slot.
|
|
10
28
|
*/
|
|
@@ -14,16 +32,16 @@ export type ConnectionSelector = {
|
|
|
14
32
|
};
|
|
15
33
|
type FetchConfig = ZeroConfig['query'];
|
|
16
34
|
export type HeaderOptions = {
|
|
17
|
-
apiKey?: string | undefined;
|
|
18
|
-
customHeaders?: Record<string, string
|
|
19
|
-
allowedClientHeaders?: readonly string[] | undefined;
|
|
20
|
-
cookie?: string | undefined;
|
|
21
|
-
origin?: string | undefined;
|
|
35
|
+
readonly apiKey?: string | undefined;
|
|
36
|
+
readonly customHeaders?: Readonly<Record<string, string>> | undefined;
|
|
37
|
+
readonly allowedClientHeaders?: readonly string[] | undefined;
|
|
38
|
+
readonly cookie?: string | undefined;
|
|
39
|
+
readonly origin?: string | undefined;
|
|
22
40
|
};
|
|
23
41
|
export type ConnectionFetchContext = {
|
|
24
|
-
url: string | undefined;
|
|
25
|
-
allowedUrlPatterns: URLPattern[] | undefined;
|
|
26
|
-
headerOptions: HeaderOptions;
|
|
42
|
+
readonly url: string | undefined;
|
|
43
|
+
readonly allowedUrlPatterns: readonly URLPattern[] | undefined;
|
|
44
|
+
readonly headerOptions: HeaderOptions;
|
|
27
45
|
};
|
|
28
46
|
/**
|
|
29
47
|
* A snapshot of one live connection tracked by the manager.
|
|
@@ -31,19 +49,19 @@ export type ConnectionFetchContext = {
|
|
|
31
49
|
* `revalidateAt` is only populated while the connection is `validated`.
|
|
32
50
|
*/
|
|
33
51
|
export type ConnectionContext = {
|
|
34
|
-
state: ConnectionState;
|
|
52
|
+
readonly state: ConnectionState;
|
|
35
53
|
readonly clientID: string;
|
|
36
54
|
readonly wsID: string;
|
|
37
|
-
readonly
|
|
38
|
-
auth: Auth | undefined;
|
|
55
|
+
readonly user: UserState;
|
|
56
|
+
readonly auth: Auth | undefined;
|
|
39
57
|
readonly profileID: string | null;
|
|
40
58
|
readonly baseCookie: string | null;
|
|
41
59
|
readonly protocolVersion: number;
|
|
42
|
-
revision: number;
|
|
43
|
-
revalidateAt: number | undefined;
|
|
60
|
+
readonly revision: number;
|
|
61
|
+
readonly revalidateAt: number | undefined;
|
|
44
62
|
readonly insertionOrder: number;
|
|
45
63
|
readonly queryContext: ConnectionFetchContext;
|
|
46
|
-
readonly
|
|
64
|
+
readonly mutateContext: ConnectionFetchContext;
|
|
47
65
|
};
|
|
48
66
|
/**
|
|
49
67
|
* Group-scoped auth state shared across the live connections.
|
|
@@ -51,28 +69,25 @@ export type ConnectionContext = {
|
|
|
51
69
|
* The background connection is the validated connection currently used for
|
|
52
70
|
* shared background work. Retransform happens on a group level, and uses
|
|
53
71
|
* the background connection's credential to refetch the latest queries.
|
|
54
|
-
*
|
|
55
|
-
* Since auth can be pinned to logged-out users, `userID` can be undefined
|
|
56
|
-
* even after validation.
|
|
57
72
|
*/
|
|
58
73
|
export type GroupAuthState = {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
maintenanceNotBeforeAt: number | undefined;
|
|
74
|
+
readonly pinnedUser: UserState | undefined;
|
|
75
|
+
readonly backgroundConnection: ConnectionSelector | undefined;
|
|
76
|
+
readonly retransformAt: number | undefined;
|
|
77
|
+
readonly maintenanceNotBeforeAt: number | undefined;
|
|
64
78
|
};
|
|
65
79
|
export type ConnectionContextManager = {
|
|
66
80
|
registerConnection(selector: ConnectionSelector, connectParams: ConnectParams, auth?: Auth): Readonly<ConnectionContext>;
|
|
67
81
|
initConnection(selector: ConnectionSelector, body: InitConnectionBody): Readonly<ConnectionContext>;
|
|
68
82
|
updateAuth(selector: ConnectionSelector, body: UpdateAuthBody): Promise<Readonly<ConnectionContext>>;
|
|
69
|
-
validateConnection(selector: ConnectionSelector, revision: number): Readonly<{
|
|
83
|
+
validateConnection(selector: ConnectionSelector, revision: number, validation: ConnectionValidation): Readonly<{
|
|
70
84
|
connection: ConnectionContext;
|
|
71
85
|
group: GroupAuthState;
|
|
72
86
|
}> | undefined;
|
|
73
87
|
failConnection(selector: ConnectionSelector, revision: number): Readonly<ConnectionContext> | undefined;
|
|
74
88
|
closeConnection(selector: ConnectionSelector): Readonly<ConnectionContext> | undefined;
|
|
75
89
|
markBackgroundRetransformSuccess(selector: ConnectionSelector, revision: number): void;
|
|
90
|
+
setSharedRetransformReady(ready: boolean): void;
|
|
76
91
|
deferMaintenance(kind: 'revalidate' | 'retransform'): void;
|
|
77
92
|
getConnectionContext(selector: ConnectionSelector): Readonly<ConnectionContext> | undefined;
|
|
78
93
|
mustGetConnectionContext(selector: ConnectionSelector): Readonly<ConnectionContext>;
|
|
@@ -90,10 +105,8 @@ export type ConnectionContextManager = {
|
|
|
90
105
|
*
|
|
91
106
|
* Connections are registered as `provisional`, optionally backfilled with
|
|
92
107
|
* `initConnection` metadata, and then promoted to `validated` once their
|
|
93
|
-
*
|
|
108
|
+
* effective `userID` is confirmed as valid. The manager also tracks which
|
|
94
109
|
* validated connection currently serves as the group's background connection.
|
|
95
|
-
*
|
|
96
|
-
* This is intentionally side-effect free.
|
|
97
110
|
*/
|
|
98
111
|
export declare class ConnectionContextManagerImpl implements ConnectionContextManager {
|
|
99
112
|
#private;
|
|
@@ -126,7 +139,7 @@ export declare class ConnectionContextManagerImpl implements ConnectionContextMa
|
|
|
126
139
|
* background connection if none is currently available. If the websocket is
|
|
127
140
|
* gone by the time async validation finishes, this becomes a no-op.
|
|
128
141
|
*/
|
|
129
|
-
validateConnection(selector: ConnectionSelector, revision: number): Readonly<{
|
|
142
|
+
validateConnection(selector: ConnectionSelector, revision: number, validation: ConnectionValidation): Readonly<{
|
|
130
143
|
connection: ConnectionContext;
|
|
131
144
|
group: GroupAuthState;
|
|
132
145
|
}> | undefined;
|
|
@@ -140,6 +153,7 @@ export declare class ConnectionContextManagerImpl implements ConnectionContextMa
|
|
|
140
153
|
* clears the deadline if it is not.
|
|
141
154
|
*/
|
|
142
155
|
markBackgroundRetransformSuccess(selector: ConnectionSelector, revision: number): void;
|
|
156
|
+
setSharedRetransformReady(ready: boolean): void;
|
|
143
157
|
deferMaintenance(kind: 'revalidate' | 'retransform'): void;
|
|
144
158
|
/** Returns the current live record for a client slot, if any. */
|
|
145
159
|
getConnectionContext(selector: ConnectionSelector): Readonly<ConnectionContext> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-context-manager.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/connection-context-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,0CAA0C,CAAC;AAGjF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,8CAA8C,CAAC;AACjF,OAAO,EAGL,KAAK,IAAI,EACT,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAC;AAG5D,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iCAAiC,CAAC;AAEnE,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,WAAW,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;AAEvC,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"connection-context-manager.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/connection-context-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,20 +9,17 @@ import { authEquals, resolveAuth } from "../../auth/auth.js";
|
|
|
9
9
|
*
|
|
10
10
|
* Connections are registered as `provisional`, optionally backfilled with
|
|
11
11
|
* `initConnection` metadata, and then promoted to `validated` once their
|
|
12
|
-
*
|
|
12
|
+
* effective `userID` is confirmed as valid. The manager also tracks which
|
|
13
13
|
* validated connection currently serves as the group's background connection.
|
|
14
|
-
*
|
|
15
|
-
* This is intentionally side-effect free.
|
|
16
14
|
*/
|
|
17
15
|
var ConnectionContextManagerImpl = class {
|
|
18
16
|
#lc;
|
|
19
17
|
#connections = /* @__PURE__ */ new Map();
|
|
20
18
|
#group = {
|
|
21
|
-
|
|
19
|
+
pinnedUser: void 0,
|
|
22
20
|
backgroundConnection: void 0,
|
|
23
21
|
retransformAt: void 0,
|
|
24
|
-
maintenanceNotBeforeAt: void 0
|
|
25
|
-
validated: false
|
|
22
|
+
maintenanceNotBeforeAt: void 0
|
|
26
23
|
};
|
|
27
24
|
#validateLegacyJWT;
|
|
28
25
|
#now;
|
|
@@ -30,6 +27,7 @@ var ConnectionContextManagerImpl = class {
|
|
|
30
27
|
#retransformIntervalMs;
|
|
31
28
|
#queryConfig;
|
|
32
29
|
#pushConfig;
|
|
30
|
+
#sharedRetransformReady = false;
|
|
33
31
|
#nextInsertionOrder = 0;
|
|
34
32
|
constructor(lc, revalidateIntervalSeconds, retransformIntervalSeconds, queryConfig, pushConfig, validateLegacyJWT, now) {
|
|
35
33
|
this.#lc = lc;
|
|
@@ -48,49 +46,39 @@ var ConnectionContextManagerImpl = class {
|
|
|
48
46
|
*/
|
|
49
47
|
registerConnection(selector, connectParams, auth) {
|
|
50
48
|
this.#removeConnection(selector);
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
const getContext = (type) => {
|
|
50
|
+
const config = type === "query" ? this.#queryConfig : this.#pushConfig;
|
|
51
|
+
return {
|
|
52
|
+
url: config?.url?.[0],
|
|
53
|
+
allowedUrlPatterns: config?.url?.map(compileUrlPattern),
|
|
54
|
+
headerOptions: {
|
|
55
|
+
customHeaders: void 0,
|
|
56
|
+
origin: connectParams.origin,
|
|
57
|
+
apiKey: config?.apiKey,
|
|
58
|
+
allowedClientHeaders: cloneAllowedClientHeaders(config?.allowedClientHeaders),
|
|
59
|
+
cookie: config?.forwardCookies ? connectParams.httpCookie : void 0
|
|
60
|
+
}
|
|
61
|
+
};
|
|
56
62
|
};
|
|
57
63
|
const connection = {
|
|
58
64
|
state: "provisional",
|
|
59
65
|
clientID: connectParams.clientID,
|
|
60
66
|
wsID: connectParams.wsID,
|
|
61
67
|
revision: 0,
|
|
62
|
-
|
|
68
|
+
user: { id: connectParams.userID ?? null },
|
|
63
69
|
auth,
|
|
64
70
|
profileID: connectParams.profileID,
|
|
65
71
|
baseCookie: connectParams.baseCookie,
|
|
66
72
|
protocolVersion: connectParams.protocolVersion,
|
|
67
73
|
revalidateAt: void 0,
|
|
68
|
-
queryContext:
|
|
69
|
-
|
|
70
|
-
allowedUrlPatterns: this.#queryConfig?.url?.map(compileUrlPattern),
|
|
71
|
-
headerOptions: {
|
|
72
|
-
...sharedHeaders,
|
|
73
|
-
apiKey: this.#queryConfig?.apiKey,
|
|
74
|
-
allowedClientHeaders: this.#queryConfig?.allowedClientHeaders,
|
|
75
|
-
cookie: this.#queryConfig?.forwardCookies ? connectParams.httpCookie : void 0
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
pushContext: {
|
|
79
|
-
url: this.#pushConfig?.url?.[0],
|
|
80
|
-
allowedUrlPatterns: this.#pushConfig?.url?.map(compileUrlPattern),
|
|
81
|
-
headerOptions: {
|
|
82
|
-
...sharedHeaders,
|
|
83
|
-
apiKey: this.#pushConfig?.apiKey,
|
|
84
|
-
allowedClientHeaders: this.#pushConfig?.allowedClientHeaders,
|
|
85
|
-
cookie: this.#pushConfig?.forwardCookies ? connectParams.httpCookie : void 0
|
|
86
|
-
}
|
|
87
|
-
},
|
|
74
|
+
queryContext: getContext("query"),
|
|
75
|
+
mutateContext: getContext("mutate"),
|
|
88
76
|
insertionOrder: ++this.#nextInsertionOrder
|
|
89
77
|
};
|
|
90
|
-
this.#
|
|
78
|
+
this.#storeConnection(connection);
|
|
91
79
|
this.#refreshBackgroundConnectionContext();
|
|
92
80
|
this.#updateBackgroundRetransformDeadline(false);
|
|
93
|
-
return
|
|
81
|
+
return connection;
|
|
94
82
|
}
|
|
95
83
|
/**
|
|
96
84
|
* Backfills `initConnection` data for sockets that were registered before the
|
|
@@ -100,13 +88,36 @@ var ConnectionContextManagerImpl = class {
|
|
|
100
88
|
*/
|
|
101
89
|
initConnection(selector, body) {
|
|
102
90
|
const connection = this.#mustGetConnectionContext(selector);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (body.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
91
|
+
let queryContext = connection.queryContext;
|
|
92
|
+
let mutateContext = connection.mutateContext;
|
|
93
|
+
if (body.userQueryURL) queryContext = {
|
|
94
|
+
...queryContext,
|
|
95
|
+
url: body.userQueryURL
|
|
96
|
+
};
|
|
97
|
+
if (body.userQueryHeaders) queryContext = {
|
|
98
|
+
...queryContext,
|
|
99
|
+
headerOptions: {
|
|
100
|
+
...queryContext.headerOptions,
|
|
101
|
+
customHeaders: cloneCustomHeaders(body.userQueryHeaders)
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
if (body.userPushURL) mutateContext = {
|
|
105
|
+
...mutateContext,
|
|
106
|
+
url: body.userPushURL
|
|
107
|
+
};
|
|
108
|
+
if (body.userPushHeaders) mutateContext = {
|
|
109
|
+
...mutateContext,
|
|
110
|
+
headerOptions: {
|
|
111
|
+
...mutateContext.headerOptions,
|
|
112
|
+
customHeaders: cloneCustomHeaders(body.userPushHeaders)
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
return this.#demoteConnection({
|
|
116
|
+
...connection,
|
|
117
|
+
revision: connection.revision + 1,
|
|
118
|
+
queryContext,
|
|
119
|
+
mutateContext
|
|
120
|
+
});
|
|
110
121
|
}
|
|
111
122
|
/**
|
|
112
123
|
* A material auth change demotes the connection back to provisional until it
|
|
@@ -114,14 +125,17 @@ var ConnectionContextManagerImpl = class {
|
|
|
114
125
|
*/
|
|
115
126
|
async updateAuth(selector, body) {
|
|
116
127
|
const connection = this.#mustGetConnectionContext(selector);
|
|
117
|
-
const nextAuth = await resolveAuth(this.#lc, connection.auth, connection.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
connection.revision
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return
|
|
128
|
+
const nextAuth = await resolveAuth(this.#lc, connection.auth, connection.user.id, body.auth, this.#validateLegacyJWT);
|
|
129
|
+
if (!authEquals(connection.auth, nextAuth)) return this.#demoteConnection({
|
|
130
|
+
...connection,
|
|
131
|
+
auth: nextAuth,
|
|
132
|
+
revision: connection.revision + 1
|
|
133
|
+
});
|
|
134
|
+
if (nextAuth === connection.auth) return connection;
|
|
135
|
+
return this.#storeConnection({
|
|
136
|
+
...connection,
|
|
137
|
+
auth: nextAuth
|
|
138
|
+
});
|
|
125
139
|
}
|
|
126
140
|
/**
|
|
127
141
|
* Validates one connection against the group's pinned `userID`.
|
|
@@ -132,7 +146,7 @@ var ConnectionContextManagerImpl = class {
|
|
|
132
146
|
* background connection if none is currently available. If the websocket is
|
|
133
147
|
* gone by the time async validation finishes, this becomes a no-op.
|
|
134
148
|
*/
|
|
135
|
-
validateConnection(selector, revision) {
|
|
149
|
+
validateConnection(selector, revision, validation) {
|
|
136
150
|
const connection = this.#getConnectionContext(selector);
|
|
137
151
|
if (!connection) return;
|
|
138
152
|
if (connection.revision !== revision) {
|
|
@@ -143,21 +157,34 @@ var ConnectionContextManagerImpl = class {
|
|
|
143
157
|
});
|
|
144
158
|
return;
|
|
145
159
|
}
|
|
146
|
-
|
|
160
|
+
let validatedUserState;
|
|
161
|
+
if (validation.kind === "server-validated") {
|
|
162
|
+
validatedUserState = { id: validation.validatedUserID };
|
|
163
|
+
if (connection.user.id !== validatedUserState.id) throw new ProtocolErrorWithLevel({
|
|
164
|
+
kind: Unauthorized,
|
|
165
|
+
message: "Connection userID does not match validated server userID.",
|
|
166
|
+
origin: ZeroCache
|
|
167
|
+
}, "warn");
|
|
168
|
+
}
|
|
169
|
+
const incomingUserState = validatedUserState ?? connection.user;
|
|
170
|
+
if (this.#group.pinnedUser !== void 0 && this.#group.pinnedUser.id !== incomingUserState.id) throw new ProtocolErrorWithLevel({
|
|
147
171
|
kind: Unauthorized,
|
|
148
172
|
message: "Client groups are pinned to a single userID. Connection userID does not match existing client group userID.",
|
|
149
173
|
origin: ZeroCache
|
|
150
174
|
}, "warn");
|
|
151
|
-
if (
|
|
152
|
-
this.#group
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
175
|
+
if (this.#group.pinnedUser === void 0) this.#setGroup({
|
|
176
|
+
...this.#group,
|
|
177
|
+
pinnedUser: incomingUserState
|
|
178
|
+
});
|
|
179
|
+
const validatedConnection = this.#storeConnection({
|
|
180
|
+
...connection,
|
|
181
|
+
state: "validated",
|
|
182
|
+
revalidateAt: this.#nextRevalidateAt()
|
|
183
|
+
});
|
|
184
|
+
this.#refreshBackgroundConnectionContext(validatedConnection);
|
|
158
185
|
this.#updateBackgroundRetransformDeadline(false);
|
|
159
186
|
return {
|
|
160
|
-
connection:
|
|
187
|
+
connection: validatedConnection,
|
|
161
188
|
group: this.getGroupState()
|
|
162
189
|
};
|
|
163
190
|
}
|
|
@@ -177,25 +204,33 @@ var ConnectionContextManagerImpl = class {
|
|
|
177
204
|
markBackgroundRetransformSuccess(selector, revision) {
|
|
178
205
|
const backgroundConnection = this.#getBackgroundConnectionContext();
|
|
179
206
|
if (!backgroundConnection) return;
|
|
180
|
-
if (
|
|
207
|
+
if (backgroundConnection.clientID !== selector.clientID || backgroundConnection.wsID !== selector.wsID || backgroundConnection.revision !== revision) return;
|
|
208
|
+
this.#updateBackgroundRetransformDeadline(true);
|
|
209
|
+
}
|
|
210
|
+
setSharedRetransformReady(ready) {
|
|
211
|
+
if (this.#sharedRetransformReady === ready) return;
|
|
212
|
+
this.#sharedRetransformReady = ready;
|
|
181
213
|
this.#updateBackgroundRetransformDeadline(true);
|
|
182
214
|
}
|
|
183
215
|
deferMaintenance(kind) {
|
|
184
216
|
const intervalMs = kind === "revalidate" ? this.#revalidateIntervalMs : this.#retransformIntervalMs;
|
|
185
217
|
if (intervalMs === void 0) return;
|
|
186
|
-
this.#
|
|
218
|
+
this.#setGroup({
|
|
219
|
+
...this.#group,
|
|
220
|
+
maintenanceNotBeforeAt: Math.max(this.#group.maintenanceNotBeforeAt ?? 0, this.#now() + intervalMs)
|
|
221
|
+
});
|
|
187
222
|
}
|
|
188
223
|
/** Returns the current live record for a client slot, if any. */
|
|
189
224
|
getConnectionContext(selector) {
|
|
190
|
-
return
|
|
225
|
+
return this.#getConnectionContext(selector);
|
|
191
226
|
}
|
|
192
227
|
/** Returns the live record for one websocket or throws if it is unavailable. */
|
|
193
228
|
mustGetConnectionContext(selector) {
|
|
194
|
-
return
|
|
229
|
+
return this.#mustGetConnectionContext(selector);
|
|
195
230
|
}
|
|
196
231
|
/** Returns the current background connection, if one exists. */
|
|
197
232
|
getBackgroundConnectionContext() {
|
|
198
|
-
return
|
|
233
|
+
return this.#getBackgroundConnectionContext();
|
|
199
234
|
}
|
|
200
235
|
mustGetBackgroundConnectionContext() {
|
|
201
236
|
const backgroundConnection = this.#getBackgroundConnectionContext();
|
|
@@ -208,7 +243,7 @@ var ConnectionContextManagerImpl = class {
|
|
|
208
243
|
}
|
|
209
244
|
/** Returns the shared group auth state. */
|
|
210
245
|
getGroupState() {
|
|
211
|
-
return
|
|
246
|
+
return this.#group;
|
|
212
247
|
}
|
|
213
248
|
/**
|
|
214
249
|
* Reports which maintenance work is currently due.
|
|
@@ -224,7 +259,7 @@ var ConnectionContextManagerImpl = class {
|
|
|
224
259
|
let earliestDeadlineAt = this.#group.retransformAt;
|
|
225
260
|
for (const connection of this.#connections.values()) {
|
|
226
261
|
if (connection.state !== "validated" || connection.revalidateAt === void 0) continue;
|
|
227
|
-
if (connection.revalidateAt <= now) dueRevalidations.push(
|
|
262
|
+
if (connection.revalidateAt <= now) dueRevalidations.push(connection);
|
|
228
263
|
earliestDeadlineAt = minDefined(earliestDeadlineAt, connection.revalidateAt);
|
|
229
264
|
}
|
|
230
265
|
const dueRetransform = this.#group.retransformAt !== void 0 && this.#group.retransformAt <= now;
|
|
@@ -252,17 +287,20 @@ var ConnectionContextManagerImpl = class {
|
|
|
252
287
|
});
|
|
253
288
|
return;
|
|
254
289
|
}
|
|
255
|
-
const snapshot = snapshotConnection(connection);
|
|
256
290
|
this.#connections.delete(connection.clientID);
|
|
257
291
|
this.#refreshBackgroundConnectionContext();
|
|
258
292
|
this.#updateBackgroundRetransformDeadline(false);
|
|
259
|
-
return
|
|
293
|
+
return connection;
|
|
260
294
|
}
|
|
261
295
|
#demoteConnection(connection) {
|
|
262
|
-
|
|
263
|
-
|
|
296
|
+
const demotedConnection = this.#storeConnection({
|
|
297
|
+
...connection,
|
|
298
|
+
state: "provisional",
|
|
299
|
+
revalidateAt: void 0
|
|
300
|
+
});
|
|
264
301
|
this.#refreshBackgroundConnectionContext();
|
|
265
302
|
this.#updateBackgroundRetransformDeadline(false);
|
|
303
|
+
return demotedConnection;
|
|
266
304
|
}
|
|
267
305
|
/**
|
|
268
306
|
* Keeps the background connection sticky while it remains validated.
|
|
@@ -277,10 +315,10 @@ var ConnectionContextManagerImpl = class {
|
|
|
277
315
|
const currentBackgroundConnection = this.#getBackgroundConnectionContext();
|
|
278
316
|
if (currentBackgroundConnection?.clientID === preferred.clientID && currentBackgroundConnection.wsID === preferred.wsID) return;
|
|
279
317
|
if (currentBackgroundConnection !== void 0) return;
|
|
280
|
-
this.#
|
|
318
|
+
this.#setBackgroundConnection({
|
|
281
319
|
clientID: preferred.clientID,
|
|
282
320
|
wsID: preferred.wsID
|
|
283
|
-
};
|
|
321
|
+
});
|
|
284
322
|
this.#lc.debug?.("Selected background connection for shared auth work", {
|
|
285
323
|
clientID: preferred.clientID,
|
|
286
324
|
wsID: preferred.wsID,
|
|
@@ -291,10 +329,10 @@ var ConnectionContextManagerImpl = class {
|
|
|
291
329
|
}
|
|
292
330
|
if (this.#getBackgroundConnectionContext()?.state === "validated") return;
|
|
293
331
|
const nextBackgroundConnection = [...this.#connections.values()].filter((connection) => connection.state === "validated").sort(comparePreferredValidatedConnection).at(0);
|
|
294
|
-
this.#
|
|
332
|
+
this.#setBackgroundConnection(nextBackgroundConnection ? {
|
|
295
333
|
clientID: nextBackgroundConnection.clientID,
|
|
296
334
|
wsID: nextBackgroundConnection.wsID
|
|
297
|
-
} : void 0;
|
|
335
|
+
} : void 0);
|
|
298
336
|
if (nextBackgroundConnection) this.#lc.debug?.("Selected background connection for shared auth work", {
|
|
299
337
|
clientID: nextBackgroundConnection.clientID,
|
|
300
338
|
wsID: nextBackgroundConnection.wsID,
|
|
@@ -322,6 +360,21 @@ var ConnectionContextManagerImpl = class {
|
|
|
322
360
|
}, "warn");
|
|
323
361
|
return connection;
|
|
324
362
|
}
|
|
363
|
+
#storeConnection(connection) {
|
|
364
|
+
this.#connections.set(connection.clientID, connection);
|
|
365
|
+
return connection;
|
|
366
|
+
}
|
|
367
|
+
#setGroup(group) {
|
|
368
|
+
this.#group = group;
|
|
369
|
+
return group;
|
|
370
|
+
}
|
|
371
|
+
#setBackgroundConnection(backgroundConnection) {
|
|
372
|
+
if (sameConnectionSelector(this.#group.backgroundConnection, backgroundConnection)) return;
|
|
373
|
+
this.#setGroup({
|
|
374
|
+
...this.#group,
|
|
375
|
+
backgroundConnection: backgroundConnection ? { ...backgroundConnection } : void 0
|
|
376
|
+
});
|
|
377
|
+
}
|
|
325
378
|
/**
|
|
326
379
|
* Keeps the group background retransform deadline coherent with current
|
|
327
380
|
* schedulability.
|
|
@@ -329,45 +382,26 @@ var ConnectionContextManagerImpl = class {
|
|
|
329
382
|
* When `reset` is false, this seeds a deadline only when shared retransform
|
|
330
383
|
* is now possible and no deadline exists yet, preserving any existing
|
|
331
384
|
* cadence. When `reset` is true, it starts a fresh interval from `#now()` if
|
|
332
|
-
* retransform is schedulable
|
|
385
|
+
* retransform is schedulable for the current ready ViewSyncer instance, or
|
|
386
|
+
* clears the deadline if it is not.
|
|
333
387
|
*/
|
|
334
388
|
#updateBackgroundRetransformDeadline(reset) {
|
|
335
|
-
if (!this.#getBackgroundConnectionContext() || this.#retransformIntervalMs === void 0) {
|
|
336
|
-
this.#group.retransformAt
|
|
389
|
+
if (!this.#getBackgroundConnectionContext() || this.#retransformIntervalMs === void 0 || !this.#sharedRetransformReady) {
|
|
390
|
+
if (this.#group.retransformAt !== void 0) this.#setGroup({
|
|
391
|
+
...this.#group,
|
|
392
|
+
retransformAt: void 0
|
|
393
|
+
});
|
|
337
394
|
return;
|
|
338
395
|
}
|
|
339
|
-
if (reset || this.#group.retransformAt === void 0) this.#
|
|
396
|
+
if (reset || this.#group.retransformAt === void 0) this.#setGroup({
|
|
397
|
+
...this.#group,
|
|
398
|
+
retransformAt: this.#now() + this.#retransformIntervalMs
|
|
399
|
+
});
|
|
340
400
|
}
|
|
341
401
|
#nextRevalidateAt() {
|
|
342
402
|
return this.#revalidateIntervalMs === void 0 ? void 0 : this.#now() + this.#revalidateIntervalMs;
|
|
343
403
|
}
|
|
344
404
|
};
|
|
345
|
-
function snapshotConnection(connection) {
|
|
346
|
-
if (!connection) return;
|
|
347
|
-
return {
|
|
348
|
-
...connection,
|
|
349
|
-
queryContext: {
|
|
350
|
-
...connection.queryContext,
|
|
351
|
-
headerOptions: {
|
|
352
|
-
...connection.queryContext.headerOptions,
|
|
353
|
-
customHeaders: connection.queryContext.headerOptions.customHeaders ? { ...connection.queryContext.headerOptions.customHeaders } : void 0
|
|
354
|
-
}
|
|
355
|
-
},
|
|
356
|
-
pushContext: {
|
|
357
|
-
...connection.pushContext,
|
|
358
|
-
headerOptions: {
|
|
359
|
-
...connection.pushContext.headerOptions,
|
|
360
|
-
customHeaders: connection.pushContext.headerOptions.customHeaders ? { ...connection.pushContext.headerOptions.customHeaders } : void 0
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
function snapshotGroup(group) {
|
|
366
|
-
return {
|
|
367
|
-
...group,
|
|
368
|
-
backgroundConnection: group.backgroundConnection ? { ...group.backgroundConnection } : void 0
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
405
|
function compareByInsertionOrder(a, b) {
|
|
372
406
|
return a.insertionOrder - b.insertionOrder || a.wsID.localeCompare(b.wsID);
|
|
373
407
|
}
|
|
@@ -379,6 +413,15 @@ function minDefined(a, b) {
|
|
|
379
413
|
if (b === void 0) return a;
|
|
380
414
|
return Math.min(a, b);
|
|
381
415
|
}
|
|
416
|
+
function sameConnectionSelector(a, b) {
|
|
417
|
+
return a?.clientID === b?.clientID && a?.wsID === b?.wsID;
|
|
418
|
+
}
|
|
419
|
+
function cloneCustomHeaders(headers) {
|
|
420
|
+
return headers ? { ...headers } : void 0;
|
|
421
|
+
}
|
|
422
|
+
function cloneAllowedClientHeaders(headers) {
|
|
423
|
+
return headers ? [...headers] : void 0;
|
|
424
|
+
}
|
|
382
425
|
//#endregion
|
|
383
426
|
export { ConnectionContextManagerImpl };
|
|
384
427
|
|