@rocicorp/zero 0.25.0-canary.11 → 0.25.0-canary.13
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/zero/package.json.js +1 -1
- package/out/zero/src/pg.js +4 -2
- package/out/zero/src/server.js +4 -2
- package/out/zero-cache/src/server/otel-diag-logger.js +1 -0
- package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
- package/out/zero-client/src/client/bindings.d.ts +2 -3
- package/out/zero-client/src/client/bindings.d.ts.map +1 -1
- package/out/zero-client/src/client/bindings.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +3 -3
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +8 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +4 -3
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/error.d.ts +6 -1
- package/out/zero-client/src/client/error.d.ts.map +1 -1
- package/out/zero-client/src/client/error.js +2 -2
- package/out/zero-client/src/client/error.js.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts +6 -9
- package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.js +3 -8
- package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.d.ts +3 -2
- package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +15 -3
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +3 -3
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts +1 -2
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +8 -8
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +5 -7
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-react/src/components/inspector.d.ts +1 -2
- package/out/zero-react/src/components/inspector.d.ts.map +1 -1
- package/out/zero-react/src/components/inspector.js.map +1 -1
- package/out/zero-react/src/components/zero-inspector.d.ts +1 -2
- package/out/zero-react/src/components/zero-inspector.d.ts.map +1 -1
- package/out/zero-react/src/components/zero-inspector.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +1 -2
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-react/src/zero-provider.d.ts +4 -5
- package/out/zero-react/src/zero-provider.d.ts.map +1 -1
- package/out/zero-react/src/zero-provider.js.map +1 -1
- package/out/zero-schema/src/permissions.d.ts +3 -0
- package/out/zero-schema/src/permissions.d.ts.map +1 -1
- package/out/zero-schema/src/permissions.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +1 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +10 -6
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +9 -18
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.d.ts.map +1 -1
- package/out/zero-server/src/push-processor.js +10 -8
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +14 -2
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +18 -15
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-solid/src/use-zero.d.ts +4 -5
- package/out/zero-solid/src/use-zero.d.ts.map +1 -1
- package/out/zero-solid/src/use-zero.js.map +1 -1
- package/out/zero-types/src/default-types.d.ts +2 -2
- 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 +0 -1
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/ivm/data.js +0 -11
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +2 -2
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +34 -20
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +1 -1
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +4 -2
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +1 -1
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +9 -3
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +4 -6
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +14 -27
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +1 -1
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +4 -2
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts +0 -1
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +0 -2
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +2 -15
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +10 -83
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +4 -3
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +24 -23
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +0 -12
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/skip.d.ts +0 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +3 -11
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts +0 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +0 -17
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +0 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +0 -3
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts +0 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js +0 -3
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +1 -2
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/custom.d.ts +2 -2
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts +33 -15
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +2 -8
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +50 -25
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js +2 -3
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/query/create-builder.d.ts +2 -2
- package/out/zql/src/query/create-builder.d.ts.map +1 -1
- package/out/zql/src/query/create-builder.js +12 -3
- package/out/zql/src/query/create-builder.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +0 -1
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +0 -3
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query-internals.d.ts.map +1 -1
- package/out/zql/src/query/query-internals.js +2 -2
- package/out/zql/src/query/query-internals.js.map +1 -1
- package/out/zql/src/query/query-registry.d.ts +126 -58
- package/out/zql/src/query/query-registry.d.ts.map +1 -1
- package/out/zql/src/query/query-registry.js +13 -21
- package/out/zql/src/query/query-registry.js.map +1 -1
- package/out/zql/src/query/query.d.ts +18 -5
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +6 -10
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
package/out/zero/package.json.js
CHANGED
package/out/zero/src/pg.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ApplicationError, isApplicationError, wrapWithApplicationError } from "../../zero-protocol/src/application-error.js";
|
|
2
2
|
import { customMutatorKey, splitMutatorKey } from "../../zql/src/mutate/custom.js";
|
|
3
3
|
import { TransactionImpl, makeSchemaCRUD, makeServerTransaction } from "../../zero-server/src/custom.js";
|
|
4
|
-
import { OutOfOrderMutation, getMutation, handleMutationRequest } from "../../zero-server/src/process-mutations.js";
|
|
4
|
+
import { OutOfOrderMutation, getMutation, handleMutateRequest, handleMutationRequest } from "../../zero-server/src/process-mutations.js";
|
|
5
5
|
import { PushProcessor } from "../../zero-server/src/push-processor.js";
|
|
6
|
-
import { handleGetQueriesRequest, handleTransformRequest } from "../../zero-server/src/queries/process-queries.js";
|
|
6
|
+
import { handleGetQueriesRequest, handleQueryRequest, handleTransformRequest } from "../../zero-server/src/queries/process-queries.js";
|
|
7
7
|
import { ZQLDatabase } from "../../zero-server/src/zql-database.js";
|
|
8
8
|
import { PostgresJSConnection, PostgresJsTransactionInternal, zeroPostgresJS } from "../../zero-server/src/adapters/postgresjs.js";
|
|
9
9
|
export {
|
|
@@ -17,7 +17,9 @@ export {
|
|
|
17
17
|
customMutatorKey,
|
|
18
18
|
getMutation,
|
|
19
19
|
handleGetQueriesRequest,
|
|
20
|
+
handleMutateRequest,
|
|
20
21
|
handleMutationRequest,
|
|
22
|
+
handleQueryRequest,
|
|
21
23
|
handleTransformRequest,
|
|
22
24
|
isApplicationError,
|
|
23
25
|
makeSchemaCRUD,
|
package/out/zero/src/server.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ApplicationError, isApplicationError, wrapWithApplicationError } from "../../zero-protocol/src/application-error.js";
|
|
2
2
|
import { customMutatorKey, splitMutatorKey } from "../../zql/src/mutate/custom.js";
|
|
3
3
|
import { TransactionImpl, makeSchemaCRUD, makeServerTransaction } from "../../zero-server/src/custom.js";
|
|
4
|
-
import { OutOfOrderMutation, getMutation, handleMutationRequest } from "../../zero-server/src/process-mutations.js";
|
|
4
|
+
import { OutOfOrderMutation, getMutation, handleMutateRequest, handleMutationRequest } from "../../zero-server/src/process-mutations.js";
|
|
5
5
|
import { PushProcessor } from "../../zero-server/src/push-processor.js";
|
|
6
|
-
import { handleGetQueriesRequest, handleTransformRequest } from "../../zero-server/src/queries/process-queries.js";
|
|
6
|
+
import { handleGetQueriesRequest, handleQueryRequest, handleTransformRequest } from "../../zero-server/src/queries/process-queries.js";
|
|
7
7
|
import { ZQLDatabase } from "../../zero-server/src/zql-database.js";
|
|
8
8
|
export {
|
|
9
9
|
ApplicationError,
|
|
@@ -14,7 +14,9 @@ export {
|
|
|
14
14
|
customMutatorKey,
|
|
15
15
|
getMutation,
|
|
16
16
|
handleGetQueriesRequest,
|
|
17
|
+
handleMutateRequest,
|
|
17
18
|
handleMutationRequest,
|
|
19
|
+
handleQueryRequest,
|
|
18
20
|
handleTransformRequest,
|
|
19
21
|
isApplicationError,
|
|
20
22
|
makeSchemaCRUD,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otel-diag-logger.js","sources":["../../../../../zero-cache/src/server/otel-diag-logger.ts"],"sourcesContent":["import {diag, DiagLogLevel} from '@opentelemetry/api';\nimport type {LogContext} from '@rocicorp/logger';\n\nfunction getOtelLogLevel(level: string | undefined): DiagLogLevel | undefined {\n if (!level) return undefined;\n\n const normalizedLevel = level.toLowerCase();\n switch (normalizedLevel) {\n case 'none':\n return DiagLogLevel.NONE;\n case 'error':\n return DiagLogLevel.ERROR;\n case 'warn':\n case 'warning':\n return DiagLogLevel.WARN;\n case 'info':\n return DiagLogLevel.INFO;\n case 'debug':\n return DiagLogLevel.DEBUG;\n case 'verbose':\n return DiagLogLevel.VERBOSE;\n case 'all':\n return DiagLogLevel.ALL;\n default:\n return undefined;\n }\n}\n\nlet diagLoggerConfigured = false;\n\n/**\n * Sets up the OpenTelemetry diagnostic logger with custom error handling and suppression.\n * This function can be called multiple times safely - it will only configure the logger once per LogContext.\n *\n * @param lc LogContext for routing OTEL diagnostic messages to the application logger\n * @param force If true, will reconfigure even if already configured (useful after NodeSDK setup)\n * @returns true if the logger was configured, false if it was already configured and not forced\n */\nexport function setupOtelDiagnosticLogger(\n lc?: LogContext,\n force = false,\n): boolean {\n if (!lc) {\n return false;\n }\n\n if (!force && diagLoggerConfigured) {\n return false;\n }\n\n const log = lc.withContext('component', 'otel');\n diag.setLogger(\n {\n verbose: (msg: string, ...args: unknown[]) => log.debug?.(msg, ...args),\n debug: (msg: string, ...args: unknown[]) => log.debug?.(msg, ...args),\n info: (msg: string, ...args: unknown[]) => log.info?.(msg, ...args),\n warn: (msg: string, ...args: unknown[]) => log.warn?.(msg, ...args),\n error: (msg: string, ...args: unknown[]) => {\n if (shouldWarnForOtelError(msg)) {\n log.warn?.(msg, ...args);\n } else {\n log.error?.(msg, ...args);\n }\n },\n },\n {\n logLevel:\n getOtelLogLevel(process.env.OTEL_LOG_LEVEL) ?? DiagLogLevel.ERROR,\n suppressOverrideMessage: true,\n },\n );\n\n diagLoggerConfigured = true;\n return true;\n}\n\n/**\n * Reset the diagnostic logger configuration state.\n * This is primarily useful for testing scenarios.\n */\nexport function resetOtelDiagnosticLogger(): void {\n diagLoggerConfigured = false;\n}\n\nconst NON_CRITICAL_OTEL_ERRORS = [\n 'request timeout',\n 'unexpected server response: 502',\n 'export failed with retryable status',\n 'metrics export failed',\n 'method not allowed',\n 'socket hang up',\n];\n\nfunction shouldWarnForOtelError(msg: string): boolean {\n const errorMessage = String(msg ?? '').toLowerCase();\n return NON_CRITICAL_OTEL_ERRORS.some(pattern =>\n errorMessage.includes(pattern),\n );\n}\n"],"names":[],"mappings":";AAGA,SAAS,gBAAgB,OAAqD;AAC5E,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,kBAAkB,MAAM,YAAA;AAC9B,UAAQ,iBAAA;AAAA,IACN,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AAAA,IACL,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB;AACE,aAAO;AAAA,EAAA;AAEb;AAEA,IAAI,uBAAuB;AAUpB,SAAS,0BACd,IACA,QAAQ,OACC;AACT,MAAI,CAAC,IAAI;AACP,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,SAAS,sBAAsB;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,GAAG,YAAY,aAAa,MAAM;AAC9C,OAAK;AAAA,IACH;AAAA,MACE,SAAS,CAAC,QAAgB,SAAoB,IAAI,QAAQ,KAAK,GAAG,IAAI;AAAA,MACtE,OAAO,CAAC,QAAgB,SAAoB,IAAI,QAAQ,KAAK,GAAG,IAAI;AAAA,MACpE,MAAM,CAAC,QAAgB,SAAoB,IAAI,OAAO,KAAK,GAAG,IAAI;AAAA,MAClE,MAAM,CAAC,QAAgB,SAAoB,IAAI,OAAO,KAAK,GAAG,IAAI;AAAA,MAClE,OAAO,CAAC,QAAgB,SAAoB;AAC1C,YAAI,uBAAuB,GAAG,GAAG;AAC/B,cAAI,OAAO,KAAK,GAAG,IAAI;AAAA,QACzB,OAAO;AACL,cAAI,QAAQ,KAAK,GAAG,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,IAAA;AAAA,IAEF;AAAA,MACE,UACE,gBAAgB,QAAQ,IAAI,cAAc,KAAK,aAAa;AAAA,MAC9D,yBAAyB;AAAA,IAAA;AAAA,EAC3B;AAGF,yBAAuB;AACvB,SAAO;AACT;AAUA,MAAM,2BAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,uBAAuB,KAAsB;AACpD,QAAM,eAAe,OAAO,OAAO,EAAE,EAAE,YAAA;AACvC,SAAO,yBAAyB;AAAA,IAAK,CAAA,YACnC,aAAa,SAAS,OAAO;AAAA,EAAA;AAEjC;"}
|
|
1
|
+
{"version":3,"file":"otel-diag-logger.js","sources":["../../../../../zero-cache/src/server/otel-diag-logger.ts"],"sourcesContent":["import {diag, DiagLogLevel} from '@opentelemetry/api';\nimport type {LogContext} from '@rocicorp/logger';\n\nfunction getOtelLogLevel(level: string | undefined): DiagLogLevel | undefined {\n if (!level) return undefined;\n\n const normalizedLevel = level.toLowerCase();\n switch (normalizedLevel) {\n case 'none':\n return DiagLogLevel.NONE;\n case 'error':\n return DiagLogLevel.ERROR;\n case 'warn':\n case 'warning':\n return DiagLogLevel.WARN;\n case 'info':\n return DiagLogLevel.INFO;\n case 'debug':\n return DiagLogLevel.DEBUG;\n case 'verbose':\n return DiagLogLevel.VERBOSE;\n case 'all':\n return DiagLogLevel.ALL;\n default:\n return undefined;\n }\n}\n\nlet diagLoggerConfigured = false;\n\n/**\n * Sets up the OpenTelemetry diagnostic logger with custom error handling and suppression.\n * This function can be called multiple times safely - it will only configure the logger once per LogContext.\n *\n * @param lc LogContext for routing OTEL diagnostic messages to the application logger\n * @param force If true, will reconfigure even if already configured (useful after NodeSDK setup)\n * @returns true if the logger was configured, false if it was already configured and not forced\n */\nexport function setupOtelDiagnosticLogger(\n lc?: LogContext,\n force = false,\n): boolean {\n if (!lc) {\n return false;\n }\n\n if (!force && diagLoggerConfigured) {\n return false;\n }\n\n const log = lc.withContext('component', 'otel');\n diag.setLogger(\n {\n verbose: (msg: string, ...args: unknown[]) => log.debug?.(msg, ...args),\n debug: (msg: string, ...args: unknown[]) => log.debug?.(msg, ...args),\n info: (msg: string, ...args: unknown[]) => log.info?.(msg, ...args),\n warn: (msg: string, ...args: unknown[]) => log.warn?.(msg, ...args),\n error: (msg: string, ...args: unknown[]) => {\n if (shouldWarnForOtelError(msg)) {\n log.warn?.(msg, ...args);\n } else {\n log.error?.(msg, ...args);\n }\n },\n },\n {\n logLevel:\n getOtelLogLevel(process.env.OTEL_LOG_LEVEL) ?? DiagLogLevel.ERROR,\n suppressOverrideMessage: true,\n },\n );\n\n diagLoggerConfigured = true;\n return true;\n}\n\n/**\n * Reset the diagnostic logger configuration state.\n * This is primarily useful for testing scenarios.\n */\nexport function resetOtelDiagnosticLogger(): void {\n diagLoggerConfigured = false;\n}\n\nconst NON_CRITICAL_OTEL_ERRORS = [\n 'request timeout',\n 'unexpected server response: 502',\n 'export failed with retryable status',\n 'export took longer than',\n 'metrics export failed',\n 'method not allowed',\n 'socket hang up',\n];\n\nfunction shouldWarnForOtelError(msg: string): boolean {\n const errorMessage = String(msg ?? '').toLowerCase();\n return NON_CRITICAL_OTEL_ERRORS.some(pattern =>\n errorMessage.includes(pattern),\n );\n}\n"],"names":[],"mappings":";AAGA,SAAS,gBAAgB,OAAqD;AAC5E,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,kBAAkB,MAAM,YAAA;AAC9B,UAAQ,iBAAA;AAAA,IACN,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AAAA,IACL,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB;AACE,aAAO;AAAA,EAAA;AAEb;AAEA,IAAI,uBAAuB;AAUpB,SAAS,0BACd,IACA,QAAQ,OACC;AACT,MAAI,CAAC,IAAI;AACP,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,SAAS,sBAAsB;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,GAAG,YAAY,aAAa,MAAM;AAC9C,OAAK;AAAA,IACH;AAAA,MACE,SAAS,CAAC,QAAgB,SAAoB,IAAI,QAAQ,KAAK,GAAG,IAAI;AAAA,MACtE,OAAO,CAAC,QAAgB,SAAoB,IAAI,QAAQ,KAAK,GAAG,IAAI;AAAA,MACpE,MAAM,CAAC,QAAgB,SAAoB,IAAI,OAAO,KAAK,GAAG,IAAI;AAAA,MAClE,MAAM,CAAC,QAAgB,SAAoB,IAAI,OAAO,KAAK,GAAG,IAAI;AAAA,MAClE,OAAO,CAAC,QAAgB,SAAoB;AAC1C,YAAI,uBAAuB,GAAG,GAAG;AAC/B,cAAI,OAAO,KAAK,GAAG,IAAI;AAAA,QACzB,OAAO;AACL,cAAI,QAAQ,KAAK,GAAG,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,IAAA;AAAA,IAEF;AAAA,MACE,UACE,gBAAgB,QAAQ,IAAI,cAAc,KAAK,aAAa;AAAA,MAC9D,yBAAyB;AAAA,IAAA;AAAA,EAC3B;AAGF,yBAAuB;AACvB,SAAO;AACT;AAUA,MAAM,2BAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,uBAAuB,KAAsB;AACpD,QAAM,eAAe,OAAO,OAAO,EAAE,EAAE,YAAA;AACvC,SAAO,yBAAyB;AAAA,IAAK,CAAA,YACnC,aAAa,SAAS,OAAO;AAAA,EAAA;AAEjC;"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { Schema } from '../../../zero-types/src/schema.ts';
|
|
2
2
|
import type { Format, ViewFactory } from '../../../zql/src/ivm/view.ts';
|
|
3
|
-
import type { AnyMutatorRegistry } from '../../../zql/src/mutate/mutator-registry.ts';
|
|
4
3
|
import type { QueryDelegate } from '../../../zql/src/query/query-delegate.ts';
|
|
5
4
|
import type { HumanReadable, MaterializeOptions, Query } from '../../../zql/src/query/query.ts';
|
|
6
5
|
import type { TypedView } from '../../../zql/src/query/typed-view.ts';
|
|
7
6
|
import type { CustomMutatorDefs } from './custom.ts';
|
|
8
7
|
import type { Zero } from './zero.ts';
|
|
9
|
-
export declare function registerZeroDelegate<TSchema extends Schema, MD extends
|
|
8
|
+
export declare function registerZeroDelegate<TSchema extends Schema, MD extends CustomMutatorDefs | undefined, TContext>(zero: Zero<TSchema, MD, TContext>, delegate: QueryDelegate): void;
|
|
10
9
|
/**
|
|
11
10
|
* Bindings interface for Zero instances, providing methods to materialize queries
|
|
12
11
|
* and extract query metadata.
|
|
@@ -39,5 +38,5 @@ export interface BindingsForZero<TSchema extends Schema> {
|
|
|
39
38
|
*
|
|
40
39
|
* @internal This API is for bindings only, not end users.
|
|
41
40
|
*/
|
|
42
|
-
export declare function bindingsForZero<TSchema extends Schema, MD extends
|
|
41
|
+
export declare function bindingsForZero<TSchema extends Schema, MD extends CustomMutatorDefs | undefined, TContext>(zero: Zero<TSchema, MD, TContext>): BindingsForZero<TSchema>;
|
|
43
42
|
//# sourceMappingURL=bindings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/bindings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/bindings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,0CAA0C,CAAC;AAE5E,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,KAAK,EACN,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,sCAAsC,CAAC;AACpE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAapC,wBAAgB,oBAAoB,CAClC,OAAO,SAAS,MAAM,EACtB,EAAE,SAAS,iBAAiB,GAAG,SAAS,EACxC,QAAQ,EACR,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAElE;AAcD;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,MAAM;IACrD;;;OAGG;IACH,WAAW,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,EAClE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,OAAO,CAAC,EAAE,SAAS,EACnB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IAErC;;;OAGG;IACH,WAAW,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,EACrE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,EACjD,OAAO,CAAC,EAAE,kBAAkB,GAC3B,CAAC,CAAC;IAEL;;OAEG;IACH,IAAI,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,EAC3D,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GACrC,MAAM,CAAC;IAEV;;OAEG;IACH,MAAM,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,EAC7D,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GACrC,MAAM,CAAC;CACX;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,SAAS,MAAM,EACtB,EAAE,SAAS,iBAAiB,GAAG,SAAS,EACxC,QAAQ,EACR,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,CA0B7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindings.js","sources":["../../../../../zero-client/src/client/bindings.ts"],"sourcesContent":["import type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {Format, ViewFactory} from '../../../zql/src/ivm/view.ts';\nimport type {
|
|
1
|
+
{"version":3,"file":"bindings.js","sources":["../../../../../zero-client/src/client/bindings.ts"],"sourcesContent":["import type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {Format, ViewFactory} from '../../../zql/src/ivm/view.ts';\nimport type {QueryDelegate} from '../../../zql/src/query/query-delegate.ts';\nimport {asQueryInternals} from '../../../zql/src/query/query-internals.ts';\nimport type {\n HumanReadable,\n MaterializeOptions,\n Query,\n} from '../../../zql/src/query/query.ts';\nimport type {TypedView} from '../../../zql/src/query/typed-view.ts';\nimport type {CustomMutatorDefs} from './custom.ts';\nimport type {Zero} from './zero.ts';\n\n/**\n * Internal WeakMap to store QueryDelegate for each Zero instance.\n * This is populated by Zero's constructor and allows bindings to access\n * the delegate without exposing it as a public API.\n */\nconst zeroDelegates = new WeakMap<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n Zero<any, any, any>,\n QueryDelegate\n>();\n\nexport function registerZeroDelegate<\n TSchema extends Schema,\n MD extends CustomMutatorDefs | undefined,\n TContext,\n>(zero: Zero<TSchema, MD, TContext>, delegate: QueryDelegate): void {\n zeroDelegates.set(zero, delegate);\n}\n\nfunction mustGetDelegate<\n TSchema extends Schema,\n MD extends CustomMutatorDefs | undefined,\n TContext,\n>(zero: Zero<TSchema, MD, TContext>): QueryDelegate {\n const delegate = zeroDelegates.get(zero);\n if (!delegate) {\n throw new Error('Zero instance not registered with bindings');\n }\n return delegate;\n}\n\n/**\n * Bindings interface for Zero instances, providing methods to materialize queries\n * and extract query metadata.\n *\n * @internal This API is for bindings only, not end users.\n */\nexport interface BindingsForZero<TSchema extends Schema> {\n /**\n * Materialize a query into a reactive view without a custom factory.\n * Returns a TypedView that automatically updates when underlying data changes.\n */\n materialize<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n factory?: undefined,\n options?: MaterializeOptions,\n ): TypedView<HumanReadable<TReturn>>;\n\n /**\n * Materialize a query into a reactive view using a custom factory.\n * The factory can transform the view into a framework-specific reactive object.\n */\n materialize<TTable extends keyof TSchema['tables'] & string, TReturn, T>(\n query: Query<TTable, TSchema, TReturn>,\n factory: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ): T;\n\n /**\n * Compute the hash of a query for caching and deduplication purposes.\n */\n hash<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n ): string;\n\n /**\n * Get the format/schema of a query's result set.\n */\n format<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n ): Format;\n}\n\n/**\n * Create a bindings object for a Zero instance.\n * This provides low-level access to query materialization and metadata extraction.\n *\n * @internal This API is for bindings only, not end users.\n */\nexport function bindingsForZero<\n TSchema extends Schema,\n MD extends CustomMutatorDefs | undefined,\n TContext,\n>(zero: Zero<TSchema, MD, TContext>): BindingsForZero<TSchema> {\n const delegate = mustGetDelegate(zero);\n\n return {\n materialize<TTable extends keyof TSchema['tables'] & string, TReturn, T>(\n query: Query<TTable, TSchema, TReturn>,\n factory?: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ) {\n return delegate.materialize(query, factory, options);\n },\n\n hash<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n ): string {\n const queryInternals = asQueryInternals(query);\n return queryInternals.hash();\n },\n\n format<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n ): Format {\n const queryInternals = asQueryInternals(query);\n return queryInternals.format;\n },\n };\n}\n"],"names":[],"mappings":";AAkBA,MAAM,oCAAoB,QAAA;AAMnB,SAAS,qBAId,MAAmC,UAA+B;AAClE,gBAAc,IAAI,MAAM,QAAQ;AAClC;AAEA,SAAS,gBAIP,MAAkD;AAClD,QAAM,WAAW,cAAc,IAAI,IAAI;AACvC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AACT;AAkDO,SAAS,gBAId,MAA6D;AAC7D,QAAM,WAAW,gBAAgB,IAAI;AAErC,SAAO;AAAA,IACL,YACE,OACA,SACA,SACA;AACA,aAAO,SAAS,YAAY,OAAO,SAAS,OAAO;AAAA,IACrD;AAAA,IAEA,KACE,OACQ;AACR,YAAM,iBAAiB,iBAAiB,KAAK;AAC7C,aAAO,eAAe,KAAA;AAAA,IACxB;AAAA,IAEA,OACE,OACQ;AACR,YAAM,iBAAiB,iBAAiB,KAAK;AAC7C,aAAO,eAAe;AAAA,IACxB;AAAA,EAAA;AAEJ;"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Subscribable } from '../../../shared/src/subscribable.ts';
|
|
2
2
|
import { ConnectionStatus } from './connection-status.ts';
|
|
3
|
-
import { type AuthError, type ClosedError, type
|
|
3
|
+
import { type AuthError, type ClosedError, type DisconnectedReason, type ZeroError } from './error.ts';
|
|
4
4
|
export type ConnectionManagerState = {
|
|
5
5
|
name: ConnectionStatus.Disconnected;
|
|
6
|
-
reason:
|
|
6
|
+
reason: DisconnectedReason;
|
|
7
7
|
} | {
|
|
8
8
|
name: ConnectionStatus.Connecting;
|
|
9
9
|
attempt: number;
|
|
@@ -94,7 +94,7 @@ export declare class ConnectionManager extends Subscribable<ConnectionManagerSta
|
|
|
94
94
|
*
|
|
95
95
|
* @returns An object containing a promise that resolves on the next state change.
|
|
96
96
|
*/
|
|
97
|
-
disconnected(reason:
|
|
97
|
+
disconnected(reason: DisconnectedReason): {
|
|
98
98
|
nextStatePromise: Promise<ConnectionManagerState>;
|
|
99
99
|
};
|
|
100
100
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/connection-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,qCAAqC,CAAC;AAEjE,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,
|
|
1
|
+
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/connection-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,qCAAqC,CAAC;AAEjE,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,sBAAsB,GAC9B;IACE,IAAI,EAAE,gBAAgB,CAAC,YAAY,CAAC;IACpC,MAAM,EAAE,kBAAkB,CAAC;CAC5B,GACD;IACE,IAAI,EAAE,gBAAgB,CAAC,UAAU,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CAChC,GACD;IACE,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC;CAClC,GACD;IACE,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC;IACjC,MAAM,EAAE,SAAS,CAAC;CACnB,GACD;IACE,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC;IAC7B,MAAM,EAAE,SAAS,CAAC;CACnB,GACD;IACE,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC;IAC9B,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEN,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C,CAAC;AAEF,QAAA,MAAM,eAAe,yBAGkB,CAAC;AAExC,KAAK,wBAAwB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACjE,KAAK,8BAA8B,GAAG,OAAO,CAC3C,sBAAsB,EACtB;IAAC,IAAI,EAAE,wBAAwB,CAAA;CAAC,CACjC,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;;gBAgC7D,OAAO,EAAE,wBAAwB;IAiB7C,IAAI,KAAK,IAAI,sBAAsB,CAElC;IAED;;OAEG;IACH,EAAE,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO;IAIrC;;;OAGG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;;OAGG;IACH,MAAM,CAAC,eAAe,CACpB,KAAK,EAAE,sBAAsB,GAC5B,KAAK,IAAI,8BAA8B;IAM1C;;;;OAIG;IACH,qBAAqB,IAAI,OAAO;IAIhC;;;OAGG;IACH,kBAAkB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAIrD;;;;;;;OAOG;IACH,UAAU,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG;QAC9B,gBAAgB,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;KACnD;IA+CD;;;;;OAKG;IACH,SAAS,IAAI;QAAC,gBAAgB,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;KAAC;IAsBhE;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG;QACxC,gBAAgB,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;KACnD;IA6BD;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG;QAC5B,gBAAgB,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;KACnD;IAuBD;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;QACxB,gBAAgB,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;KACnD;IAuBD;;;OAGG;IACH,MAAM;IAqBG,OAAO,QAAO,IAAI,CAGzB;CA4DH;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,sBAAsB,SAkBnE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.js","sources":["../../../../../zero-client/src/client/connection-manager.ts"],"sourcesContent":["import {resolver, type Resolver} from '@rocicorp/resolver';\nimport {Subscribable} from '../../../shared/src/subscribable.ts';\nimport {ClientErrorKind} from './client-error-kind.ts';\nimport {ConnectionStatus} from './connection-status.ts';\nimport {\n ClientError,\n isClientError,\n type AuthError,\n type ClosedError,\n type OfflineError,\n type ZeroError,\n} from './error.ts';\n\nconst DEFAULT_TIMEOUT_CHECK_INTERVAL_MS = 1_000;\n\nexport type ConnectionManagerState =\n | {\n name: ConnectionStatus.Disconnected;\n reason: OfflineError;\n }\n | {\n name: ConnectionStatus.Connecting;\n attempt: number;\n disconnectAt: number;\n reason?: ZeroError | undefined;\n }\n | {\n name: ConnectionStatus.Connected;\n }\n | {\n name: ConnectionStatus.NeedsAuth;\n reason: AuthError;\n }\n | {\n name: ConnectionStatus.Error;\n reason: ZeroError;\n }\n | {\n name: ConnectionStatus.Closed;\n reason: ClosedError;\n };\n\nexport type ConnectionManagerOptions = {\n /**\n * The amount of milliseconds we allow for continuous connecting attempts before\n * transitioning to disconnected state.\n */\n disconnectTimeout: number;\n /**\n * How frequently we check whether the connecting timeout has elapsed.\n * Defaults to 1 second.\n */\n timeoutCheckIntervalMs?: number | undefined;\n};\n\nconst TERMINAL_STATES = [\n ConnectionStatus.NeedsAuth,\n ConnectionStatus.Error,\n] as const satisfies ConnectionStatus[];\n\ntype TerminalConnectionStatus = (typeof TERMINAL_STATES)[number];\ntype TerminalConnectionManagerState = Extract<\n ConnectionManagerState,\n {name: TerminalConnectionStatus}\n>;\n\nexport class ConnectionManager extends Subscribable<ConnectionManagerState> {\n #state: ConnectionManagerState;\n\n /**\n * The timestamp when we first started trying to connect.\n * This is used to track the retry window.\n * Reset to undefined when we successfully connect or when we transition to disconnected.\n */\n #connectingStartedAt: number | undefined;\n\n /**\n * The amount of milliseconds we allow for continuous connecting attempts before\n * transitioning to disconnected state.\n */\n #disconnectTimeout: number;\n\n /**\n * Handle for the timeout interval that periodically checks whether we've\n * exceeded the allowed connecting window.\n */\n #timeoutInterval: ReturnType<typeof setInterval> | undefined;\n\n /**\n * Interval duration for checking whether the connecting timeout has elapsed.\n */\n #timeoutCheckIntervalMs: number;\n\n /**\n * Resolver used to signal waiting callers when the state changes.\n */\n #stateChangeResolver: Resolver<ConnectionManagerState> = resolver();\n\n constructor(options: ConnectionManagerOptions) {\n super();\n\n const now = Date.now();\n\n this.#disconnectTimeout = options.disconnectTimeout;\n this.#timeoutCheckIntervalMs =\n options.timeoutCheckIntervalMs ?? DEFAULT_TIMEOUT_CHECK_INTERVAL_MS;\n this.#state = {\n name: ConnectionStatus.Connecting,\n attempt: 0,\n disconnectAt: now + this.#disconnectTimeout,\n };\n this.#connectingStartedAt = now;\n this.#maybeStartTimeoutInterval();\n }\n\n get state(): ConnectionManagerState {\n return this.#state;\n }\n\n /**\n * Returns true if the current state is equal to the given status.\n */\n is(status: ConnectionStatus): boolean {\n return this.#state.name === status;\n }\n\n /**\n * Returns true if the current state is a terminal state\n * that can be recovered from by calling connect().\n */\n isInTerminalState(): boolean {\n return ConnectionManager.isTerminalState(this.#state);\n }\n\n /**\n * Returns true if the given status is a terminal state\n * that can be recovered from by calling connect().\n */\n static isTerminalState(\n state: ConnectionManagerState,\n ): state is TerminalConnectionManagerState {\n return (TERMINAL_STATES as readonly ConnectionStatus[]).includes(\n state.name,\n );\n }\n\n /**\n * Returns true if the run loop should continue.\n * The run loop continues in all states except closed.\n * In needs-auth and error states, the run loop pauses and waits for connect() to be called.\n */\n shouldContinueRunLoop(): boolean {\n return this.#state.name !== ConnectionStatus.Closed;\n }\n\n /**\n * Waits for the next state change.\n * @returns A promise that resolves when the next state change occurs.\n */\n waitForStateChange(): Promise<ConnectionManagerState> {\n return this.#nextStatePromise();\n }\n\n /**\n * Transition to connecting state.\n *\n * This starts the timeout timer, but if we've entered disconnected state,\n * we stay there and continue retrying.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n connecting(reason?: ZeroError): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // we cannot intentionally transition from disconnected to connecting\n // disconnected can transition to connected on successful connection\n // or a terminal state\n if (this.#state.name === ConnectionStatus.Disconnected) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n const now = Date.now();\n\n // If we're already connecting, increment the attempt counter\n if (this.#state.name === ConnectionStatus.Connecting) {\n this.#state = {\n ...this.#state,\n attempt: this.#state.attempt + 1,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n this.#maybeStartTimeoutInterval();\n return {nextStatePromise};\n }\n\n // Starting a new connecting session\n // If #connectingStartedAt is undefined, this is a fresh start - set it to now\n // If it's already set, we're retrying within the same retry window, so keep it\n if (this.#connectingStartedAt === undefined) {\n this.#connectingStartedAt = now;\n }\n\n const disconnectAt = this.#connectingStartedAt + this.#disconnectTimeout;\n\n this.#state = {\n name: ConnectionStatus.Connecting,\n attempt: 1,\n disconnectAt,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n this.#maybeStartTimeoutInterval();\n return {nextStatePromise};\n }\n\n /**\n * Transition to connected state.\n * This resets the connecting timeout timer.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n connected(): {nextStatePromise: Promise<ConnectionManagerState>} {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already connected, no-op\n if (this.#state.name === ConnectionStatus.Connected) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Reset the timeout timer on successful connection\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Connected,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to disconnected state.\n * This is called when the timeout expires.\n * The run loop will continue trying to reconnect.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n disconnected(reason: OfflineError): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already disconnected, no-op\n if (this.#state.name === ConnectionStatus.Disconnected) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // When transitioning from connected to disconnected, we've lost a connection\n // we previously had. Clear the timeout timer so we can start a fresh timeout window.\n if (this.#state.name === ConnectionStatus.Connected) {\n this.#connectingStartedAt = undefined;\n }\n // When transitioning from connecting to disconnected (e.g., due to timeout),\n // we keep the start time to maintain the context that we've been trying for a while.\n\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Disconnected,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to needs-auth state.\n * This pauses the run loop until connect() is called with new credentials.\n * Resets the retry window and attempt counter.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n needsAuth(reason: AuthError): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already in needs-auth state, no-op\n if (this.#state.name === ConnectionStatus.NeedsAuth) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Reset the timeout timer and connecting start time\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.NeedsAuth,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to error state.\n * This pauses the run loop until connect() is called.\n * Resets the retry window and attempt counter.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n error(reason: ZeroError): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already in error state, no-op\n if (this.#state.name === ConnectionStatus.Error) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Reset the timeout timer and connecting start time\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Error,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to closed state.\n * This is terminal - no further transitions are allowed.\n */\n closed() {\n // Already closed, no-op\n if (this.#state.name === ConnectionStatus.Closed) {\n return;\n }\n\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Closed,\n reason: new ClientError({\n kind: ClientErrorKind.ClientClosed,\n message: 'Zero was explicitly closed by calling zero.close()',\n }),\n };\n this.#publishState();\n this.cleanup();\n return;\n }\n\n override cleanup = (): void => {\n this._listeners.clear();\n this.#resolveNextStateWaiters();\n };\n\n #resolveNextStateWaiters(): void {\n this.#stateChangeResolver.resolve(this.#state);\n this.#stateChangeResolver = resolver();\n }\n\n #publishState(): void {\n this.notify(this.#state);\n this.#resolveNextStateWaiters();\n }\n\n #nextStatePromise(): Promise<ConnectionManagerState> {\n return this.#stateChangeResolver.promise;\n }\n\n #publishStateAndGetPromise(): Promise<ConnectionManagerState> {\n this.#publishState();\n return this.#nextStatePromise();\n }\n\n /**\n * Check if we should transition from connecting to disconnected due to timeout.\n * Returns true if the transition happened.\n */\n #checkTimeout(): boolean {\n if (this.#state.name !== ConnectionStatus.Connecting) {\n return false;\n }\n\n const now = Date.now();\n if (now >= this.#state.disconnectAt) {\n this.disconnected(\n new ClientError({\n kind: ClientErrorKind.Offline,\n message: `Zero was unable to connect for ${Math.floor(this.#disconnectTimeout / 1_000)} seconds and was disconnected`,\n }),\n );\n return true;\n }\n\n return false;\n }\n\n #maybeStartTimeoutInterval(): void {\n if (this.#timeoutInterval !== undefined) {\n return;\n }\n this.#timeoutInterval = setInterval(() => {\n this.#checkTimeout();\n }, this.#timeoutCheckIntervalMs);\n }\n\n #maybeStopTimeoutInterval(): void {\n if (this.#timeoutInterval === undefined) {\n return;\n }\n clearInterval(this.#timeoutInterval);\n this.#timeoutInterval = undefined;\n }\n}\n\n/**\n * Used to trigger the catch block when a terminal state is reached.\n *\n * @param state - The current connection state.\n */\nexport const throwIfConnectionError = (state: ConnectionManagerState) => {\n if (\n ConnectionManager.isTerminalState(state) ||\n state.name === ConnectionStatus.Closed ||\n ((state.name === ConnectionStatus.Connecting ||\n state.name === ConnectionStatus.Disconnected) &&\n state.reason)\n ) {\n if (\n isClientError(state.reason) &&\n (state.reason.kind === ClientErrorKind.ConnectTimeout ||\n state.reason.kind === ClientErrorKind.AbruptClose ||\n state.reason.kind === ClientErrorKind.CleanClose)\n ) {\n return;\n }\n throw state.reason;\n }\n};\n"],"names":["ConnectionStatus.NeedsAuth","ConnectionStatus.Error","ConnectionStatus.Connecting","ConnectionStatus.Closed","ConnectionStatus.Disconnected","nextStatePromise","ConnectionStatus.Connected","ClientErrorKind.ClientClosed","ClientErrorKind.Offline","ClientErrorKind.ConnectTimeout","ClientErrorKind.AbruptClose","ClientErrorKind.CleanClose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"connection-manager.js","sources":["../../../../../zero-client/src/client/connection-manager.ts"],"sourcesContent":["import {resolver, type Resolver} from '@rocicorp/resolver';\nimport {Subscribable} from '../../../shared/src/subscribable.ts';\nimport {ClientErrorKind} from './client-error-kind.ts';\nimport {ConnectionStatus} from './connection-status.ts';\nimport {\n ClientError,\n isClientError,\n type AuthError,\n type ClosedError,\n type DisconnectedReason,\n type ZeroError,\n} from './error.ts';\n\nconst DEFAULT_TIMEOUT_CHECK_INTERVAL_MS = 1_000;\n\nexport type ConnectionManagerState =\n | {\n name: ConnectionStatus.Disconnected;\n reason: DisconnectedReason;\n }\n | {\n name: ConnectionStatus.Connecting;\n attempt: number;\n disconnectAt: number;\n reason?: ZeroError | undefined;\n }\n | {\n name: ConnectionStatus.Connected;\n }\n | {\n name: ConnectionStatus.NeedsAuth;\n reason: AuthError;\n }\n | {\n name: ConnectionStatus.Error;\n reason: ZeroError;\n }\n | {\n name: ConnectionStatus.Closed;\n reason: ClosedError;\n };\n\nexport type ConnectionManagerOptions = {\n /**\n * The amount of milliseconds we allow for continuous connecting attempts before\n * transitioning to disconnected state.\n */\n disconnectTimeout: number;\n /**\n * How frequently we check whether the connecting timeout has elapsed.\n * Defaults to 1 second.\n */\n timeoutCheckIntervalMs?: number | undefined;\n};\n\nconst TERMINAL_STATES = [\n ConnectionStatus.NeedsAuth,\n ConnectionStatus.Error,\n] as const satisfies ConnectionStatus[];\n\ntype TerminalConnectionStatus = (typeof TERMINAL_STATES)[number];\ntype TerminalConnectionManagerState = Extract<\n ConnectionManagerState,\n {name: TerminalConnectionStatus}\n>;\n\nexport class ConnectionManager extends Subscribable<ConnectionManagerState> {\n #state: ConnectionManagerState;\n\n /**\n * The timestamp when we first started trying to connect.\n * This is used to track the retry window.\n * Reset to undefined when we successfully connect or when we transition to disconnected.\n */\n #connectingStartedAt: number | undefined;\n\n /**\n * The amount of milliseconds we allow for continuous connecting attempts before\n * transitioning to disconnected state.\n */\n #disconnectTimeout: number;\n\n /**\n * Handle for the timeout interval that periodically checks whether we've\n * exceeded the allowed connecting window.\n */\n #timeoutInterval: ReturnType<typeof setInterval> | undefined;\n\n /**\n * Interval duration for checking whether the connecting timeout has elapsed.\n */\n #timeoutCheckIntervalMs: number;\n\n /**\n * Resolver used to signal waiting callers when the state changes.\n */\n #stateChangeResolver: Resolver<ConnectionManagerState> = resolver();\n\n constructor(options: ConnectionManagerOptions) {\n super();\n\n const now = Date.now();\n\n this.#disconnectTimeout = options.disconnectTimeout;\n this.#timeoutCheckIntervalMs =\n options.timeoutCheckIntervalMs ?? DEFAULT_TIMEOUT_CHECK_INTERVAL_MS;\n this.#state = {\n name: ConnectionStatus.Connecting,\n attempt: 0,\n disconnectAt: now + this.#disconnectTimeout,\n };\n this.#connectingStartedAt = now;\n this.#maybeStartTimeoutInterval();\n }\n\n get state(): ConnectionManagerState {\n return this.#state;\n }\n\n /**\n * Returns true if the current state is equal to the given status.\n */\n is(status: ConnectionStatus): boolean {\n return this.#state.name === status;\n }\n\n /**\n * Returns true if the current state is a terminal state\n * that can be recovered from by calling connect().\n */\n isInTerminalState(): boolean {\n return ConnectionManager.isTerminalState(this.#state);\n }\n\n /**\n * Returns true if the given status is a terminal state\n * that can be recovered from by calling connect().\n */\n static isTerminalState(\n state: ConnectionManagerState,\n ): state is TerminalConnectionManagerState {\n return (TERMINAL_STATES as readonly ConnectionStatus[]).includes(\n state.name,\n );\n }\n\n /**\n * Returns true if the run loop should continue.\n * The run loop continues in all states except closed.\n * In needs-auth and error states, the run loop pauses and waits for connect() to be called.\n */\n shouldContinueRunLoop(): boolean {\n return this.#state.name !== ConnectionStatus.Closed;\n }\n\n /**\n * Waits for the next state change.\n * @returns A promise that resolves when the next state change occurs.\n */\n waitForStateChange(): Promise<ConnectionManagerState> {\n return this.#nextStatePromise();\n }\n\n /**\n * Transition to connecting state.\n *\n * This starts the timeout timer, but if we've entered disconnected state,\n * we stay there and continue retrying.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n connecting(reason?: ZeroError): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // we cannot intentionally transition from disconnected to connecting\n // disconnected can transition to connected on successful connection\n // or a terminal state\n if (this.#state.name === ConnectionStatus.Disconnected) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n const now = Date.now();\n\n // If we're already connecting, increment the attempt counter\n if (this.#state.name === ConnectionStatus.Connecting) {\n this.#state = {\n ...this.#state,\n attempt: this.#state.attempt + 1,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n this.#maybeStartTimeoutInterval();\n return {nextStatePromise};\n }\n\n // Starting a new connecting session\n // If #connectingStartedAt is undefined, this is a fresh start - set it to now\n // If it's already set, we're retrying within the same retry window, so keep it\n if (this.#connectingStartedAt === undefined) {\n this.#connectingStartedAt = now;\n }\n\n const disconnectAt = this.#connectingStartedAt + this.#disconnectTimeout;\n\n this.#state = {\n name: ConnectionStatus.Connecting,\n attempt: 1,\n disconnectAt,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n this.#maybeStartTimeoutInterval();\n return {nextStatePromise};\n }\n\n /**\n * Transition to connected state.\n * This resets the connecting timeout timer.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n connected(): {nextStatePromise: Promise<ConnectionManagerState>} {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already connected, no-op\n if (this.#state.name === ConnectionStatus.Connected) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Reset the timeout timer on successful connection\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Connected,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to disconnected state.\n * This is called when the timeout expires.\n * The run loop will continue trying to reconnect.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n disconnected(reason: DisconnectedReason): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already disconnected, no-op\n if (this.#state.name === ConnectionStatus.Disconnected) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // When transitioning from connected to disconnected, we've lost a connection\n // we previously had. Clear the timeout timer so we can start a fresh timeout window.\n if (this.#state.name === ConnectionStatus.Connected) {\n this.#connectingStartedAt = undefined;\n }\n // When transitioning from connecting to disconnected (e.g., due to timeout),\n // we keep the start time to maintain the context that we've been trying for a while.\n\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Disconnected,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to needs-auth state.\n * This pauses the run loop until connect() is called with new credentials.\n * Resets the retry window and attempt counter.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n needsAuth(reason: AuthError): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already in needs-auth state, no-op\n if (this.#state.name === ConnectionStatus.NeedsAuth) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Reset the timeout timer and connecting start time\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.NeedsAuth,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to error state.\n * This pauses the run loop until connect() is called.\n * Resets the retry window and attempt counter.\n *\n * @returns An object containing a promise that resolves on the next state change.\n */\n error(reason: ZeroError): {\n nextStatePromise: Promise<ConnectionManagerState>;\n } {\n // cannot transition from closed to any other status\n if (this.#state.name === ConnectionStatus.Closed) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Already in error state, no-op\n if (this.#state.name === ConnectionStatus.Error) {\n return {nextStatePromise: this.#nextStatePromise()};\n }\n\n // Reset the timeout timer and connecting start time\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Error,\n reason,\n };\n const nextStatePromise = this.#publishStateAndGetPromise();\n return {nextStatePromise};\n }\n\n /**\n * Transition to closed state.\n * This is terminal - no further transitions are allowed.\n */\n closed() {\n // Already closed, no-op\n if (this.#state.name === ConnectionStatus.Closed) {\n return;\n }\n\n this.#connectingStartedAt = undefined;\n this.#maybeStopTimeoutInterval();\n\n this.#state = {\n name: ConnectionStatus.Closed,\n reason: new ClientError({\n kind: ClientErrorKind.ClientClosed,\n message: 'Zero was explicitly closed by calling zero.close()',\n }),\n };\n this.#publishState();\n this.cleanup();\n return;\n }\n\n override cleanup = (): void => {\n this._listeners.clear();\n this.#resolveNextStateWaiters();\n };\n\n #resolveNextStateWaiters(): void {\n this.#stateChangeResolver.resolve(this.#state);\n this.#stateChangeResolver = resolver();\n }\n\n #publishState(): void {\n this.notify(this.#state);\n this.#resolveNextStateWaiters();\n }\n\n #nextStatePromise(): Promise<ConnectionManagerState> {\n return this.#stateChangeResolver.promise;\n }\n\n #publishStateAndGetPromise(): Promise<ConnectionManagerState> {\n this.#publishState();\n return this.#nextStatePromise();\n }\n\n /**\n * Check if we should transition from connecting to disconnected due to timeout.\n * Returns true if the transition happened.\n */\n #checkTimeout(): boolean {\n if (this.#state.name !== ConnectionStatus.Connecting) {\n return false;\n }\n\n const now = Date.now();\n if (now >= this.#state.disconnectAt) {\n this.disconnected(\n new ClientError({\n kind: ClientErrorKind.Offline,\n message: `Zero was unable to connect for ${Math.floor(this.#disconnectTimeout / 1_000)} seconds and was disconnected`,\n }),\n );\n return true;\n }\n\n return false;\n }\n\n #maybeStartTimeoutInterval(): void {\n if (this.#timeoutInterval !== undefined) {\n return;\n }\n this.#timeoutInterval = setInterval(() => {\n this.#checkTimeout();\n }, this.#timeoutCheckIntervalMs);\n }\n\n #maybeStopTimeoutInterval(): void {\n if (this.#timeoutInterval === undefined) {\n return;\n }\n clearInterval(this.#timeoutInterval);\n this.#timeoutInterval = undefined;\n }\n}\n\n/**\n * Used to trigger the catch block when a terminal state is reached.\n *\n * @param state - The current connection state.\n */\nexport const throwIfConnectionError = (state: ConnectionManagerState) => {\n if (\n ConnectionManager.isTerminalState(state) ||\n state.name === ConnectionStatus.Closed ||\n ((state.name === ConnectionStatus.Connecting ||\n state.name === ConnectionStatus.Disconnected) &&\n state.reason)\n ) {\n if (\n isClientError(state.reason) &&\n (state.reason.kind === ClientErrorKind.ConnectTimeout ||\n state.reason.kind === ClientErrorKind.AbruptClose ||\n state.reason.kind === ClientErrorKind.CleanClose)\n ) {\n return;\n }\n throw state.reason;\n }\n};\n"],"names":["ConnectionStatus.NeedsAuth","ConnectionStatus.Error","ConnectionStatus.Connecting","ConnectionStatus.Closed","ConnectionStatus.Disconnected","nextStatePromise","ConnectionStatus.Connected","ClientErrorKind.ClientClosed","ClientErrorKind.Offline","ClientErrorKind.ConnectTimeout","ClientErrorKind.AbruptClose","ClientErrorKind.CleanClose"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EACF;QACE,IAAI,EAAE,QAAQ,CAAC;QACf,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GACD;QACE,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GACD;QACE,IAAI,EAAE,YAAY,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACP,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAEpB;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IAExC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;KAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,qBAAa,cAAe,YAAW,UAAU;;gBAO7C,iBAAiB,EAAE,iBAAiB,EACpC,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,IAAI;IAQpD,IAAI,KAAK,IAAI,MAAM,CAAC,eAAe,CAAC,CAEnC;IAEK,OAAO,CAAC,IAAI,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;KAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAsCvE;AAED,qBAAa,gBAAiB,YAAW,MAAM,CAAC,eAAe,CAAC;;gBAIlD,iBAAiB,EAAE,iBAAiB;IAKhD,IAAI,OAAO,IAAI,eAAe,CAE7B;IAED,SAAS,GAAI,UAAU,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAI7D;CA0DN"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { unreachable } from "../../../shared/src/asserts.js";
|
|
2
2
|
import { PushFailed, TransformFailed } from "../../../zero-protocol/src/error-kind-enum.js";
|
|
3
|
-
import {
|
|
3
|
+
import { NoSocketOrigin } from "./client-error-kind-enum.js";
|
|
4
|
+
import { Disconnected, NeedsAuth, Error, Connecting, Connected, Closed } from "./connection-status-enum.js";
|
|
4
5
|
class ConnectionImpl {
|
|
5
6
|
#connectionManager;
|
|
6
7
|
#lc;
|
|
@@ -21,6 +22,12 @@ class ConnectionImpl {
|
|
|
21
22
|
lc.debug?.("Updating auth credential from connect()");
|
|
22
23
|
this.#setAuth(opts.auth);
|
|
23
24
|
}
|
|
25
|
+
if (this.#connectionManager.state.name === Disconnected && this.#connectionManager.state.reason.kind === NoSocketOrigin) {
|
|
26
|
+
lc.error?.(
|
|
27
|
+
"connect() called but the connection is disconnected due to a missing cacheURL. No reconnect will be attempted."
|
|
28
|
+
);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
24
31
|
if (!this.#connectionManager.isInTerminalState()) {
|
|
25
32
|
lc.debug?.(
|
|
26
33
|
"connect() called but not in a terminal state. Current state:",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sources":["../../../../../zero-client/src/client/connection.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {unreachable} from '../../../shared/src/asserts.ts';\nimport {ErrorKind} from '../../../zero-protocol/src/error-kind.ts';\nimport type {\n ConnectionManager,\n ConnectionManagerState,\n} from './connection-manager.ts';\nimport {ConnectionStatus} from './connection-status.ts';\n\n/**\n * The current connection state of the Zero instance. One of the following states:\n *\n * - `connecting`: The client is actively trying to connect every 5 seconds.\n * - `disconnected`: The client is now in an \"offline\" state. It will continue\n * to try to connect every 5 seconds.\n * - `connected`: The client has opened a successful connection to the server.\n * - `needs-auth`: Authentication is invalid or expired. No connection retries will be made\n * until the host application calls `connect()`.\n * - `error`: A fatal error occurred. No connection retries will be made until the host\n * application calls `connect()` again.\n * - `closed`: The client was shut down (for example via `zero.close()`). This is\n * a terminal state, and a new Zero instance must be created to reconnect.\n */\nexport type ConnectionState =\n | {\n name: 'disconnected';\n reason: string;\n }\n | {\n name: 'connecting';\n reason?: string;\n }\n | {\n name: 'connected';\n }\n | {\n name: 'needs-auth';\n reason:\n | {\n type: 'mutate';\n status: 401 | 403;\n body?: string;\n }\n | {\n type: 'query';\n status: 401 | 403;\n body?: string;\n }\n | {\n type: 'zero-cache';\n reason: string;\n };\n }\n | {\n name: 'error';\n reason: string;\n }\n | {\n name: 'closed';\n reason: string;\n };\n\nexport interface Source<T> {\n /**\n * The current state value.\n */\n readonly current: T;\n\n /**\n * Subscribe to state changes.\n *\n * @param listener - Called when the state changes with the new state value.\n * @returns A function to unsubscribe from state changes.\n */\n subscribe(listener: (state: T) => void): () => void;\n}\n\n/**\n * Connection API for managing Zero's connection lifecycle.\n */\nexport interface Connection {\n /**\n * The current connection state as a subscribable value.\n */\n readonly state: Source<ConnectionState>;\n\n /**\n * Resumes the connection from a terminal state.\n *\n * If called when not in a terminal state, this method does nothing.\n *\n * @param opts - Optional connection options\n * @param opts.auth - Token to use for authentication. If provided, this overrides\n * the stored auth credential for this connection attempt.\n * If `null` or `undefined`, the stored auth credential is cleared.\n * @returns A promise that resolves once the connection state has transitioned to connecting.\n */\n connect(opts?: {auth: string | null | undefined}): Promise<void>;\n}\n\nexport class ConnectionImpl implements Connection {\n readonly #connectionManager: ConnectionManager;\n readonly #lc: LogContext;\n readonly #source: ConnectionSource;\n readonly #setAuth: (auth: string | null | undefined) => void;\n\n constructor(\n connectionManager: ConnectionManager,\n lc: LogContext,\n setAuth: (auth: string | null | undefined) => void,\n ) {\n this.#connectionManager = connectionManager;\n this.#lc = lc;\n this.#source = new ConnectionSource(connectionManager);\n this.#setAuth = setAuth;\n }\n\n get state(): Source<ConnectionState> {\n return this.#source;\n }\n\n async connect(opts?: {auth: string | null | undefined}): Promise<void> {\n const lc = this.#lc.withContext('connect');\n\n if (opts && 'auth' in opts) {\n lc.debug?.('Updating auth credential from connect()');\n this.#setAuth(opts.auth);\n }\n\n // only allow connect() to be called from a terminal state\n if (!this.#connectionManager.isInTerminalState()) {\n lc.debug?.(\n 'connect() called but not in a terminal state. Current state:',\n this.#connectionManager.state.name,\n );\n return;\n }\n\n lc.info?.(\n `Resuming connection from state: ${this.#connectionManager.state.name}`,\n );\n\n // Transition to connecting, which will trigger the state change resolver\n // and unblock the run loop. Wait for the next state change (connected, disconnected, etc.)\n const {nextStatePromise} = this.#connectionManager.connecting();\n await nextStatePromise;\n }\n}\n\nexport class ConnectionSource implements Source<ConnectionState> {\n #state: ConnectionState;\n readonly #connectionManager: ConnectionManager;\n\n constructor(connectionManager: ConnectionManager) {\n this.#connectionManager = connectionManager;\n this.#state = this.#mapConnectionManagerState(connectionManager.state);\n }\n\n get current(): ConnectionState {\n return this.#state;\n }\n\n subscribe = (listener: (s: ConnectionState) => void): (() => void) =>\n this.#connectionManager.subscribe(state => {\n this.#state = this.#mapConnectionManagerState(state);\n listener(this.#state);\n });\n\n #mapConnectionManagerState(state: ConnectionManagerState): ConnectionState {\n switch (state.name) {\n case ConnectionStatus.Closed:\n return {\n name: 'closed',\n reason: state.reason.message,\n };\n case ConnectionStatus.Connected:\n return {\n name: 'connected',\n };\n case ConnectionStatus.Connecting:\n return {\n name: 'connecting',\n ...(state.reason?.message ? {reason: state.reason.message} : {}),\n };\n case ConnectionStatus.Disconnected:\n return {\n name: 'disconnected',\n reason: state.reason.message,\n };\n case ConnectionStatus.Error:\n return {\n name: 'error',\n reason: state.reason.message,\n };\n case ConnectionStatus.NeedsAuth:\n return {\n name: 'needs-auth',\n reason:\n state.reason.errorBody.kind === ErrorKind.PushFailed\n ? {\n type: 'mutate',\n status: state.reason.errorBody.status,\n ...(state.reason.errorBody.bodyPreview\n ? {body: state.reason.errorBody.bodyPreview}\n : {}),\n }\n : state.reason.errorBody.kind === ErrorKind.TransformFailed\n ? {\n type: 'query',\n status: state.reason.errorBody.status,\n ...(state.reason.errorBody.bodyPreview\n ? {body: state.reason.errorBody.bodyPreview}\n : {}),\n }\n : {\n type: 'zero-cache',\n reason: state.reason.message,\n },\n };\n\n default:\n unreachable(state);\n }\n }\n}\n"],"names":["ConnectionStatus.
|
|
1
|
+
{"version":3,"file":"connection.js","sources":["../../../../../zero-client/src/client/connection.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {unreachable} from '../../../shared/src/asserts.ts';\nimport {ErrorKind} from '../../../zero-protocol/src/error-kind.ts';\nimport {ClientErrorKind} from './client-error-kind.ts';\nimport type {\n ConnectionManager,\n ConnectionManagerState,\n} from './connection-manager.ts';\nimport {ConnectionStatus} from './connection-status.ts';\n\n/**\n * The current connection state of the Zero instance. One of the following states:\n *\n * - `connecting`: The client is actively trying to connect every 5 seconds.\n * - `disconnected`: The client is now in an \"offline\" state. It will continue\n * to try to connect every 5 seconds.\n * - `connected`: The client has opened a successful connection to the server.\n * - `needs-auth`: Authentication is invalid or expired. No connection retries will be made\n * until the host application calls `connect()`.\n * - `error`: A fatal error occurred. No connection retries will be made until the host\n * application calls `connect()` again.\n * - `closed`: The client was shut down (for example via `zero.close()`). This is\n * a terminal state, and a new Zero instance must be created to reconnect.\n */\nexport type ConnectionState =\n | {\n name: 'disconnected';\n reason: string;\n }\n | {\n name: 'connecting';\n reason?: string;\n }\n | {\n name: 'connected';\n }\n | {\n name: 'needs-auth';\n reason:\n | {\n type: 'mutate';\n status: 401 | 403;\n body?: string;\n }\n | {\n type: 'query';\n status: 401 | 403;\n body?: string;\n }\n | {\n type: 'zero-cache';\n reason: string;\n };\n }\n | {\n name: 'error';\n reason: string;\n }\n | {\n name: 'closed';\n reason: string;\n };\n\nexport interface Source<T> {\n /**\n * The current state value.\n */\n readonly current: T;\n\n /**\n * Subscribe to state changes.\n *\n * @param listener - Called when the state changes with the new state value.\n * @returns A function to unsubscribe from state changes.\n */\n subscribe(listener: (state: T) => void): () => void;\n}\n\n/**\n * Connection API for managing Zero's connection lifecycle.\n */\nexport interface Connection {\n /**\n * The current connection state as a subscribable value.\n */\n readonly state: Source<ConnectionState>;\n\n /**\n * Resumes the connection from a terminal state.\n *\n * If called when not in a terminal state, this method does nothing.\n *\n * @param opts - Optional connection options\n * @param opts.auth - Token to use for authentication. If provided, this overrides\n * the stored auth credential for this connection attempt.\n * If `null` or `undefined`, the stored auth credential is cleared.\n * @returns A promise that resolves once the connection state has transitioned to connecting.\n */\n connect(opts?: {auth: string | null | undefined}): Promise<void>;\n}\n\nexport class ConnectionImpl implements Connection {\n readonly #connectionManager: ConnectionManager;\n readonly #lc: LogContext;\n readonly #source: ConnectionSource;\n readonly #setAuth: (auth: string | null | undefined) => void;\n\n constructor(\n connectionManager: ConnectionManager,\n lc: LogContext,\n setAuth: (auth: string | null | undefined) => void,\n ) {\n this.#connectionManager = connectionManager;\n this.#lc = lc;\n this.#source = new ConnectionSource(connectionManager);\n this.#setAuth = setAuth;\n }\n\n get state(): Source<ConnectionState> {\n return this.#source;\n }\n\n async connect(opts?: {auth: string | null | undefined}): Promise<void> {\n const lc = this.#lc.withContext('connect');\n\n if (opts && 'auth' in opts) {\n lc.debug?.('Updating auth credential from connect()');\n this.#setAuth(opts.auth);\n }\n\n // if the connection is disconnected due to a missing cacheURL, we don't allow a reconnect\n if (\n this.#connectionManager.state.name === ConnectionStatus.Disconnected &&\n this.#connectionManager.state.reason.kind ===\n ClientErrorKind.NoSocketOrigin\n ) {\n lc.error?.(\n 'connect() called but the connection is disconnected due to a missing cacheURL. No reconnect will be attempted.',\n );\n return;\n }\n\n // only allow connect() to be called from a terminal state\n if (!this.#connectionManager.isInTerminalState()) {\n lc.debug?.(\n 'connect() called but not in a terminal state. Current state:',\n this.#connectionManager.state.name,\n );\n return;\n }\n\n lc.info?.(\n `Resuming connection from state: ${this.#connectionManager.state.name}`,\n );\n\n // Transition to connecting, which will trigger the state change resolver\n // and unblock the run loop. Wait for the next state change (connected, disconnected, etc.)\n const {nextStatePromise} = this.#connectionManager.connecting();\n await nextStatePromise;\n }\n}\n\nexport class ConnectionSource implements Source<ConnectionState> {\n #state: ConnectionState;\n readonly #connectionManager: ConnectionManager;\n\n constructor(connectionManager: ConnectionManager) {\n this.#connectionManager = connectionManager;\n this.#state = this.#mapConnectionManagerState(connectionManager.state);\n }\n\n get current(): ConnectionState {\n return this.#state;\n }\n\n subscribe = (listener: (s: ConnectionState) => void): (() => void) =>\n this.#connectionManager.subscribe(state => {\n this.#state = this.#mapConnectionManagerState(state);\n listener(this.#state);\n });\n\n #mapConnectionManagerState(state: ConnectionManagerState): ConnectionState {\n switch (state.name) {\n case ConnectionStatus.Closed:\n return {\n name: 'closed',\n reason: state.reason.message,\n };\n case ConnectionStatus.Connected:\n return {\n name: 'connected',\n };\n case ConnectionStatus.Connecting:\n return {\n name: 'connecting',\n ...(state.reason?.message ? {reason: state.reason.message} : {}),\n };\n case ConnectionStatus.Disconnected:\n return {\n name: 'disconnected',\n reason: state.reason.message,\n };\n case ConnectionStatus.Error:\n return {\n name: 'error',\n reason: state.reason.message,\n };\n case ConnectionStatus.NeedsAuth:\n return {\n name: 'needs-auth',\n reason:\n state.reason.errorBody.kind === ErrorKind.PushFailed\n ? {\n type: 'mutate',\n status: state.reason.errorBody.status,\n ...(state.reason.errorBody.bodyPreview\n ? {body: state.reason.errorBody.bodyPreview}\n : {}),\n }\n : state.reason.errorBody.kind === ErrorKind.TransformFailed\n ? {\n type: 'query',\n status: state.reason.errorBody.status,\n ...(state.reason.errorBody.bodyPreview\n ? {body: state.reason.errorBody.bodyPreview}\n : {}),\n }\n : {\n type: 'zero-cache',\n reason: state.reason.message,\n },\n };\n\n default:\n unreachable(state);\n }\n }\n}\n"],"names":["ConnectionStatus.Disconnected","ClientErrorKind.NoSocketOrigin","ConnectionStatus.Closed","ConnectionStatus.Connected","ConnectionStatus.Connecting","ConnectionStatus.Error","ConnectionStatus.NeedsAuth","ErrorKind.PushFailed","ErrorKind.TransformFailed"],"mappings":";;;;AAqGO,MAAM,eAAqC;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,mBACA,IACA,SACA;AACA,SAAK,qBAAqB;AAC1B,SAAK,MAAM;AACX,SAAK,UAAU,IAAI,iBAAiB,iBAAiB;AACrD,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,QAAiC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,QAAQ,MAAyD;AACrE,UAAM,KAAK,KAAK,IAAI,YAAY,SAAS;AAEzC,QAAI,QAAQ,UAAU,MAAM;AAC1B,SAAG,QAAQ,yCAAyC;AACpD,WAAK,SAAS,KAAK,IAAI;AAAA,IACzB;AAGA,QACE,KAAK,mBAAmB,MAAM,SAASA,gBACvC,KAAK,mBAAmB,MAAM,OAAO,SACnCC,gBACF;AACA,SAAG;AAAA,QACD;AAAA,MAAA;AAEF;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,mBAAmB,qBAAqB;AAChD,SAAG;AAAA,QACD;AAAA,QACA,KAAK,mBAAmB,MAAM;AAAA,MAAA;AAEhC;AAAA,IACF;AAEA,OAAG;AAAA,MACD,mCAAmC,KAAK,mBAAmB,MAAM,IAAI;AAAA,IAAA;AAKvE,UAAM,EAAC,iBAAA,IAAoB,KAAK,mBAAmB,WAAA;AACnD,UAAM;AAAA,EACR;AACF;AAEO,MAAM,iBAAoD;AAAA,EAC/D;AAAA,EACS;AAAA,EAET,YAAY,mBAAsC;AAChD,SAAK,qBAAqB;AAC1B,SAAK,SAAS,KAAK,2BAA2B,kBAAkB,KAAK;AAAA,EACvE;AAAA,EAEA,IAAI,UAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,CAAC,aACX,KAAK,mBAAmB,UAAU,CAAA,UAAS;AACzC,SAAK,SAAS,KAAK,2BAA2B,KAAK;AACnD,aAAS,KAAK,MAAM;AAAA,EACtB,CAAC;AAAA,EAEH,2BAA2B,OAAgD;AACzE,YAAQ,MAAM,MAAA;AAAA,MACZ,KAAKC;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,MAAM,OAAO;AAAA,QAAA;AAAA,MAEzB,KAAKC;AACH,eAAO;AAAA,UACL,MAAM;AAAA,QAAA;AAAA,MAEV,KAAKC;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,GAAI,MAAM,QAAQ,UAAU,EAAC,QAAQ,MAAM,OAAO,YAAW,CAAA;AAAA,QAAC;AAAA,MAElE,KAAKJ;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,MAAM,OAAO;AAAA,QAAA;AAAA,MAEzB,KAAKK;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,MAAM,OAAO;AAAA,QAAA;AAAA,MAEzB,KAAKC;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QACE,MAAM,OAAO,UAAU,SAASC,aAC5B;AAAA,YACE,MAAM;AAAA,YACN,QAAQ,MAAM,OAAO,UAAU;AAAA,YAC/B,GAAI,MAAM,OAAO,UAAU,cACvB,EAAC,MAAM,MAAM,OAAO,UAAU,gBAC9B,CAAA;AAAA,UAAC,IAEP,MAAM,OAAO,UAAU,SAASC,kBAC9B;AAAA,YACE,MAAM;AAAA,YACN,QAAQ,MAAM,OAAO,UAAU;AAAA,YAC/B,GAAI,MAAM,OAAO,UAAU,cACvB,EAAC,MAAM,MAAM,OAAO,UAAU,gBAC9B,CAAA;AAAA,UAAC,IAEP;AAAA,YACE,MAAM;AAAA,YACN,QAAQ,MAAM,OAAO;AAAA,UAAA;AAAA,QACvB;AAAA,MAGZ;AACE,oBAAiB;AAAA,IAAA;AAAA,EAEvB;AACF;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/custom.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/custom.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { zeroData } from "../../../replicache/src/transactions.js";
|
|
|
2
2
|
import { assert } from "../../../shared/src/asserts.js";
|
|
3
3
|
import { must } from "../../../shared/src/must.js";
|
|
4
4
|
import { emptyFunction } from "../../../shared/src/sentinels.js";
|
|
5
|
-
import {
|
|
5
|
+
import { createRunnableBuilder } from "../../../zql/src/query/create-builder.js";
|
|
6
6
|
import "../../../zero-protocol/src/ast.js";
|
|
7
7
|
import { ZeroContext } from "./context.js";
|
|
8
8
|
import { deleteImpl, updateImpl, upsertImpl, insertImpl } from "./crud.js";
|
|
@@ -21,11 +21,12 @@ class TransactionImpl {
|
|
|
21
21
|
repTx,
|
|
22
22
|
txData.ivmSources
|
|
23
23
|
);
|
|
24
|
-
|
|
25
|
-
this.#zeroContext = newZeroContext(
|
|
24
|
+
const zeroContext = newZeroContext(
|
|
26
25
|
lc,
|
|
27
26
|
txData.ivmSources
|
|
28
27
|
);
|
|
28
|
+
this.query = createRunnableBuilder(zeroContext, schema);
|
|
29
|
+
this.#zeroContext = zeroContext;
|
|
29
30
|
}
|
|
30
31
|
get clientID() {
|
|
31
32
|
return this.#repTx.clientID;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.js","sources":["../../../../../zero-client/src/client/custom.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport type {ZeroTxData} from '../../../replicache/src/replicache-options.ts';\nimport type {WriteTransactionImpl} from '../../../replicache/src/transactions.ts';\nimport {zeroData} from '../../../replicache/src/transactions.ts';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {emptyFunction} from '../../../shared/src/sentinels.ts';\nimport type {TableSchema} from '../../../zero-schema/src/table-schema.ts';\nimport type {DefaultSchema} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {\n ClientTransaction,\n DeleteID,\n InsertValue,\n SchemaCRUD,\n TableCRUD,\n Transaction,\n UpdateValue,\n UpsertValue,\n} from '../../../zql/src/mutate/custom.ts';\nimport {createBuilder} from '../../../zql/src/query/create-builder.ts';\nimport {\n type HumanReadable,\n type Query,\n type RunOptions,\n} from '../../../zql/src/query/query.ts';\nimport type {SchemaQuery} from '../../../zql/src/query/schema-query.ts';\nimport type {ClientID} from '../types/client-state.ts';\nimport {ZeroContext} from './context.ts';\nimport {deleteImpl, insertImpl, updateImpl, upsertImpl} from './crud.ts';\nimport type {IVMSourceBranch} from './ivm-branch.ts';\nimport type {WriteTransaction} from './replicache-types.ts';\n\n/**\n * The shape which a user's custom mutator definitions must conform to.\n * Supports arbitrary depth nesting of namespaces.\n */\nexport type CustomMutatorDefs = {\n // oxlint-disable-next-line no-explicit-any\n [namespaceOrKey: string]: CustomMutatorImpl<any> | CustomMutatorDefs;\n};\n\nexport type MutatorResultDetails =\n | {\n readonly type: 'success';\n }\n | {\n readonly type: 'error';\n readonly error:\n | {\n readonly type: 'app';\n readonly message: string;\n readonly details: ReadonlyJSONValue | undefined;\n }\n | {\n readonly type: 'zero';\n readonly message: string;\n };\n };\n\nexport type MutatorResultSuccessDetails = Extract<\n MutatorResultDetails,\n {type: 'success'}\n>;\nexport type MutatorResultErrorDetails = Extract<\n MutatorResultDetails,\n {type: 'error'}\n>;\n\nexport type MutatorResult = {\n client: Promise<MutatorResultDetails & {}>;\n server: Promise<MutatorResultDetails & {}>;\n} & {};\n\nexport type CustomMutatorImpl<\n S extends Schema,\n TWrappedTransaction = unknown,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n TArgs = any,\n Context = unknown,\n> = (\n tx: Transaction<S, TWrappedTransaction>,\n // TODO: many args. See commit: 52657c2f934b4a458d628ea77e56ce92b61eb3c6 which did have many args.\n // The issue being that it will be a protocol change to support varargs.\n args: TArgs,\n ctx: Context,\n) => Promise<void>;\n\n/**\n * The shape exposed on the `Zero.mutate` instance.\n * The signature of a custom mutator takes a `transaction` as its first arg\n * but the user does not provide this arg when calling the mutator.\n *\n * This utility strips the `tx` arg from the user's custom mutator signatures.\n * Supports arbitrary depth nesting of namespaces.\n */\nexport type MakeCustomMutatorInterfaces<\n S extends Schema,\n MD extends CustomMutatorDefs,\n TContext,\n> = {\n readonly [NamespaceOrName in keyof MD]: MD[NamespaceOrName] extends (\n tx: Transaction<S>,\n ...args: infer Args\n ) => Promise<void>\n ? (...args: Args) => MutatorResult\n : MD[NamespaceOrName] extends CustomMutatorDefs\n ? MakeCustomMutatorInterfaces<S, MD[NamespaceOrName], TContext>\n : never;\n};\n\nexport type MakeCustomMutatorInterface<TSchema extends Schema, F> = F extends (\n tx: ClientTransaction<TSchema>,\n ...args: infer Args\n) => Promise<void>\n ? (...args: Args) => MutatorResult\n : never;\n\nexport class TransactionImpl<TSchema extends Schema = DefaultSchema>\n implements ClientTransaction<TSchema>\n{\n readonly location = 'client';\n readonly mutate: SchemaCRUD<TSchema>;\n readonly query: SchemaQuery<TSchema>;\n readonly #repTx: WriteTransaction;\n readonly #zeroContext: ZeroContext;\n\n constructor(lc: LogContext, repTx: WriteTransaction, schema: TSchema) {\n must(repTx.reason === 'initial' || repTx.reason === 'rebase');\n const txData = getZeroTxData(repTx);\n\n this.#repTx = repTx;\n this.mutate = makeSchemaCRUD(\n schema,\n repTx,\n txData.ivmSources as IVMSourceBranch,\n );\n this.query = createBuilder(schema);\n\n this.#zeroContext = newZeroContext(\n lc,\n txData.ivmSources as IVMSourceBranch,\n );\n }\n\n get clientID(): ClientID {\n return this.#repTx.clientID;\n }\n\n get mutationID(): number {\n return this.#repTx.mutationID;\n }\n\n get reason(): 'optimistic' | 'rebase' {\n return this.#repTx.reason === 'initial' ? 'optimistic' : 'rebase';\n }\n\n get token(): string | undefined {\n return (this.#repTx as WriteTransactionImpl)[zeroData]?.token;\n }\n\n run<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n return this.#zeroContext.run(query, options);\n }\n}\n\nexport function getZeroTxData(repTx: WriteTransaction): ZeroTxData {\n const txData = must(\n (repTx as WriteTransactionImpl)[zeroData],\n 'zero was not set on replicache internal options!',\n );\n return txData as ZeroTxData;\n}\n\nexport function makeReplicacheMutator<\n S extends Schema,\n TWrappedTransaction,\n Context,\n>(\n lc: LogContext,\n mutator: CustomMutatorImpl<S, TWrappedTransaction>,\n schema: S,\n context: Context,\n): (repTx: WriteTransaction, args: ReadonlyJSONValue) => Promise<void> {\n return async (\n repTx: WriteTransaction,\n args: ReadonlyJSONValue,\n ): Promise<void> => {\n const tx = new TransactionImpl(lc, repTx, schema);\n await mutator(tx, args, context);\n };\n}\n\nfunction makeSchemaCRUD<S extends Schema>(\n schema: S,\n tx: WriteTransaction,\n ivmBranch: IVMSourceBranch,\n) {\n // Only creates the CRUD mutators on demand\n // rather than creating them all up-front for each mutation.\n return new Proxy(\n {},\n {\n get(target: Record<string, TableCRUD<TableSchema>>, prop: string) {\n if (prop in target) {\n return target[prop];\n }\n\n target[prop] = makeTableCRUD(schema, prop, tx, ivmBranch);\n return target[prop];\n },\n },\n ) as SchemaCRUD<S>;\n}\n\nfunction assertValidRunOptions(options: RunOptions | undefined): void {\n // TODO(arv): We should enforce this with the type system too.\n assert(\n options?.type !== 'complete',\n 'Cannot wait for complete results in custom mutations',\n );\n}\n\nfunction newZeroContext(lc: LogContext, ivmBranch: IVMSourceBranch) {\n return new ZeroContext(\n lc,\n ivmBranch,\n () => emptyFunction,\n () => emptyFunction,\n emptyFunction,\n emptyFunction,\n emptyFunction,\n applyViewUpdates => applyViewUpdates(),\n emptyFunction,\n assertValidRunOptions,\n );\n}\n\nfunction makeTableCRUD(\n schema: Schema,\n tableName: string,\n tx: WriteTransaction,\n ivmBranch: IVMSourceBranch,\n) {\n const table = must(schema.tables[tableName]);\n const {primaryKey} = table;\n return {\n insert: (value: InsertValue<TableSchema>) =>\n insertImpl(\n tx,\n {op: 'insert', tableName, primaryKey, value},\n schema,\n ivmBranch,\n ),\n upsert: (value: UpsertValue<TableSchema>) =>\n upsertImpl(\n tx,\n {op: 'upsert', tableName, primaryKey, value},\n schema,\n ivmBranch,\n ),\n update: (value: UpdateValue<TableSchema>) =>\n updateImpl(\n tx,\n {op: 'update', tableName, primaryKey, value},\n schema,\n ivmBranch,\n ),\n delete: (id: DeleteID<TableSchema>) =>\n deleteImpl(\n tx,\n {op: 'delete', tableName, primaryKey, value: id},\n schema,\n ivmBranch,\n ),\n };\n}\n"],"names":[],"mappings":";;;;;;;;AAuHO,MAAM,gBAEb;AAAA,EACW,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,IAAgB,OAAyB,QAAiB;AACpE,SAAK,MAAM,WAAW,aAAa,MAAM,WAAW,QAAQ;AAC5D,UAAM,SAAS,cAAc,KAAK;AAElC,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,MACZ;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IAAA;AAET,SAAK,QAAQ,cAAc,MAAM;AAEjC,SAAK,eAAe;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,IAAA;AAAA,EAEX;AAAA,EAEA,IAAI,WAAqB;AACvB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,SAAkC;AACpC,WAAO,KAAK,OAAO,WAAW,YAAY,eAAe;AAAA,EAC3D;AAAA,EAEA,IAAI,QAA4B;AAC9B,WAAQ,KAAK,OAAgC,QAAQ,GAAG;AAAA,EAC1D;AAAA,EAEA,IACE,OACA,SACiC;AACjC,WAAO,KAAK,aAAa,IAAI,OAAO,OAAO;AAAA,EAC7C;AACF;AAEO,SAAS,cAAc,OAAqC;AACjE,QAAM,SAAS;AAAA,IACZ,MAA+B,QAAQ;AAAA,IACxC;AAAA,EAAA;AAEF,SAAO;AACT;AAEO,SAAS,sBAKd,IACA,SACA,QACA,SACqE;AACrE,SAAO,OACL,OACA,SACkB;AAClB,UAAM,KAAK,IAAI,gBAAgB,IAAI,OAAO,MAAM;AAChD,UAAM,QAAQ,IAAI,MAAM,OAAO;AAAA,EACjC;AACF;AAEA,SAAS,eACP,QACA,IACA,WACA;AAGA,SAAO,IAAI;AAAA,IACT,CAAA;AAAA,IACA;AAAA,MACE,IAAI,QAAgD,MAAc;AAChE,YAAI,QAAQ,QAAQ;AAClB,iBAAO,OAAO,IAAI;AAAA,QACpB;AAEA,eAAO,IAAI,IAAI,cAAc,QAAQ,MAAM,IAAI,SAAS;AACxD,eAAO,OAAO,IAAI;AAAA,MACpB;AAAA,IAAA;AAAA,EACF;AAEJ;AAEA,SAAS,sBAAsB,SAAuC;AAEpE;AAAA,IACE,SAAS,SAAS;AAAA,IAClB;AAAA,EAAA;AAEJ;AAEA,SAAS,eAAe,IAAgB,WAA4B;AAClE,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAoB,iBAAA;AAAA,IACpB;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,SAAS,cACP,QACA,WACA,IACA,WACA;AACA,QAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,CAAC;AAC3C,QAAM,EAAC,eAAc;AACrB,SAAO;AAAA,IACL,QAAQ,CAAC,UACP;AAAA,MACE;AAAA,MACA,EAAe,WAAuB,MAAA;AAAA,MACtC;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,QAAQ,CAAC,UACP;AAAA,MACE;AAAA,MACA,EAAC,IAAI,UAAU,WAAW,YAAY,MAAA;AAAA,MACtC;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,QAAQ,CAAC,UACP;AAAA,MACE;AAAA,MACA,EAAe,WAAuB,MAAA;AAAA,MACtC;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,QAAQ,CAAC,OACP;AAAA,MACE;AAAA,MACA,EAAe,WAAuB,OAAO,GAAA;AAAA,MAC7C;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAEN;"}
|
|
1
|
+
{"version":3,"file":"custom.js","sources":["../../../../../zero-client/src/client/custom.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport type {ZeroTxData} from '../../../replicache/src/replicache-options.ts';\nimport type {WriteTransactionImpl} from '../../../replicache/src/transactions.ts';\nimport {zeroData} from '../../../replicache/src/transactions.ts';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {emptyFunction} from '../../../shared/src/sentinels.ts';\nimport type {TableSchema} from '../../../zero-schema/src/table-schema.ts';\nimport type {DefaultSchema} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {\n ClientTransaction,\n DeleteID,\n InsertValue,\n SchemaCRUD,\n TableCRUD,\n Transaction,\n UpdateValue,\n UpsertValue,\n} from '../../../zql/src/mutate/custom.ts';\nimport {createRunnableBuilder} from '../../../zql/src/query/create-builder.ts';\nimport {\n type HumanReadable,\n type Query,\n type RunOptions,\n} from '../../../zql/src/query/query.ts';\nimport type {SchemaQuery} from '../../../zql/src/query/schema-query.ts';\nimport type {ClientID} from '../types/client-state.ts';\nimport {ZeroContext} from './context.ts';\nimport {deleteImpl, insertImpl, updateImpl, upsertImpl} from './crud.ts';\nimport type {IVMSourceBranch} from './ivm-branch.ts';\nimport type {WriteTransaction} from './replicache-types.ts';\n\n/**\n * The shape which a user's custom mutator definitions must conform to.\n * Supports arbitrary depth nesting of namespaces.\n */\nexport type CustomMutatorDefs = {\n // oxlint-disable-next-line no-explicit-any\n [namespaceOrKey: string]: CustomMutatorImpl<any> | CustomMutatorDefs;\n};\n\nexport type MutatorResultDetails =\n | {\n readonly type: 'success';\n }\n | {\n readonly type: 'error';\n readonly error:\n | {\n readonly type: 'app';\n readonly message: string;\n readonly details: ReadonlyJSONValue | undefined;\n }\n | {\n readonly type: 'zero';\n readonly message: string;\n };\n };\n\nexport type MutatorResultSuccessDetails = Extract<\n MutatorResultDetails,\n {type: 'success'}\n>;\nexport type MutatorResultErrorDetails = Extract<\n MutatorResultDetails,\n {type: 'error'}\n>;\n\nexport type MutatorResult = {\n client: Promise<MutatorResultDetails & {}>;\n server: Promise<MutatorResultDetails & {}>;\n} & {};\n\nexport type CustomMutatorImpl<\n S extends Schema,\n TWrappedTransaction = unknown,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n TArgs = any,\n Context = unknown,\n> = (\n tx: Transaction<S, TWrappedTransaction>,\n // TODO: many args. See commit: 52657c2f934b4a458d628ea77e56ce92b61eb3c6 which did have many args.\n // The issue being that it will be a protocol change to support varargs.\n args: TArgs,\n ctx: Context,\n) => Promise<void>;\n\n/**\n * The shape exposed on the `Zero.mutate` instance.\n * The signature of a custom mutator takes a `transaction` as its first arg\n * but the user does not provide this arg when calling the mutator.\n *\n * This utility strips the `tx` arg from the user's custom mutator signatures.\n * Supports arbitrary depth nesting of namespaces.\n */\nexport type MakeCustomMutatorInterfaces<\n S extends Schema,\n MD extends CustomMutatorDefs,\n TContext,\n> = {\n readonly [NamespaceOrName in keyof MD]: MD[NamespaceOrName] extends (\n tx: Transaction<S>,\n ...args: infer Args\n ) => Promise<void>\n ? (...args: Args) => MutatorResult\n : MD[NamespaceOrName] extends CustomMutatorDefs\n ? MakeCustomMutatorInterfaces<S, MD[NamespaceOrName], TContext>\n : never;\n};\n\nexport type MakeCustomMutatorInterface<TSchema extends Schema, F> = F extends (\n tx: ClientTransaction<TSchema>,\n ...args: infer Args\n) => Promise<void>\n ? (...args: Args) => MutatorResult\n : never;\n\nexport class TransactionImpl<TSchema extends Schema = DefaultSchema>\n implements ClientTransaction<TSchema>\n{\n readonly location = 'client';\n readonly mutate: SchemaCRUD<TSchema>;\n readonly query: SchemaQuery<TSchema>;\n readonly #repTx: WriteTransaction;\n readonly #zeroContext: ZeroContext;\n\n constructor(lc: LogContext, repTx: WriteTransaction, schema: TSchema) {\n must(repTx.reason === 'initial' || repTx.reason === 'rebase');\n const txData = getZeroTxData(repTx);\n\n this.#repTx = repTx;\n this.mutate = makeSchemaCRUD(\n schema,\n repTx,\n txData.ivmSources as IVMSourceBranch,\n );\n\n const zeroContext = newZeroContext(\n lc,\n txData.ivmSources as IVMSourceBranch,\n );\n\n this.query = createRunnableBuilder(zeroContext, schema);\n this.#zeroContext = zeroContext;\n }\n\n get clientID(): ClientID {\n return this.#repTx.clientID;\n }\n\n get mutationID(): number {\n return this.#repTx.mutationID;\n }\n\n get reason(): 'optimistic' | 'rebase' {\n return this.#repTx.reason === 'initial' ? 'optimistic' : 'rebase';\n }\n\n get token(): string | undefined {\n return (this.#repTx as WriteTransactionImpl)[zeroData]?.token;\n }\n\n run<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n return this.#zeroContext.run(query, options);\n }\n}\n\nexport function getZeroTxData(repTx: WriteTransaction): ZeroTxData {\n const txData = must(\n (repTx as WriteTransactionImpl)[zeroData],\n 'zero was not set on replicache internal options!',\n );\n return txData as ZeroTxData;\n}\n\nexport function makeReplicacheMutator<\n S extends Schema,\n TWrappedTransaction,\n Context,\n>(\n lc: LogContext,\n mutator: CustomMutatorImpl<S, TWrappedTransaction>,\n schema: S,\n context: Context,\n): (repTx: WriteTransaction, args: ReadonlyJSONValue) => Promise<void> {\n return async (\n repTx: WriteTransaction,\n args: ReadonlyJSONValue,\n ): Promise<void> => {\n const tx = new TransactionImpl(lc, repTx, schema);\n await mutator(tx, args, context);\n };\n}\n\nfunction makeSchemaCRUD<S extends Schema>(\n schema: S,\n tx: WriteTransaction,\n ivmBranch: IVMSourceBranch,\n) {\n // Only creates the CRUD mutators on demand\n // rather than creating them all up-front for each mutation.\n return new Proxy(\n {},\n {\n get(target: Record<string, TableCRUD<TableSchema>>, prop: string) {\n if (prop in target) {\n return target[prop];\n }\n\n target[prop] = makeTableCRUD(schema, prop, tx, ivmBranch);\n return target[prop];\n },\n },\n ) as SchemaCRUD<S>;\n}\n\nfunction assertValidRunOptions(options: RunOptions | undefined): void {\n // TODO(arv): We should enforce this with the type system too.\n assert(\n options?.type !== 'complete',\n 'Cannot wait for complete results in custom mutations',\n );\n}\n\nfunction newZeroContext(lc: LogContext, ivmBranch: IVMSourceBranch) {\n return new ZeroContext(\n lc,\n ivmBranch,\n () => emptyFunction,\n () => emptyFunction,\n emptyFunction,\n emptyFunction,\n emptyFunction,\n applyViewUpdates => applyViewUpdates(),\n emptyFunction,\n assertValidRunOptions,\n );\n}\n\nfunction makeTableCRUD(\n schema: Schema,\n tableName: string,\n tx: WriteTransaction,\n ivmBranch: IVMSourceBranch,\n) {\n const table = must(schema.tables[tableName]);\n const {primaryKey} = table;\n return {\n insert: (value: InsertValue<TableSchema>) =>\n insertImpl(\n tx,\n {op: 'insert', tableName, primaryKey, value},\n schema,\n ivmBranch,\n ),\n upsert: (value: UpsertValue<TableSchema>) =>\n upsertImpl(\n tx,\n {op: 'upsert', tableName, primaryKey, value},\n schema,\n ivmBranch,\n ),\n update: (value: UpdateValue<TableSchema>) =>\n updateImpl(\n tx,\n {op: 'update', tableName, primaryKey, value},\n schema,\n ivmBranch,\n ),\n delete: (id: DeleteID<TableSchema>) =>\n deleteImpl(\n tx,\n {op: 'delete', tableName, primaryKey, value: id},\n schema,\n ivmBranch,\n ),\n };\n}\n"],"names":[],"mappings":";;;;;;;;AAuHO,MAAM,gBAEb;AAAA,EACW,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,IAAgB,OAAyB,QAAiB;AACpE,SAAK,MAAM,WAAW,aAAa,MAAM,WAAW,QAAQ;AAC5D,UAAM,SAAS,cAAc,KAAK;AAElC,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,MACZ;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IAAA;AAGT,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,IAAA;AAGT,SAAK,QAAQ,sBAAsB,aAAa,MAAM;AACtD,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,IAAI,WAAqB;AACvB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,SAAkC;AACpC,WAAO,KAAK,OAAO,WAAW,YAAY,eAAe;AAAA,EAC3D;AAAA,EAEA,IAAI,QAA4B;AAC9B,WAAQ,KAAK,OAAgC,QAAQ,GAAG;AAAA,EAC1D;AAAA,EAEA,IACE,OACA,SACiC;AACjC,WAAO,KAAK,aAAa,IAAI,OAAO,OAAO;AAAA,EAC7C;AACF;AAEO,SAAS,cAAc,OAAqC;AACjE,QAAM,SAAS;AAAA,IACZ,MAA+B,QAAQ;AAAA,IACxC;AAAA,EAAA;AAEF,SAAO;AACT;AAEO,SAAS,sBAKd,IACA,SACA,QACA,SACqE;AACrE,SAAO,OACL,OACA,SACkB;AAClB,UAAM,KAAK,IAAI,gBAAgB,IAAI,OAAO,MAAM;AAChD,UAAM,QAAQ,IAAI,MAAM,OAAO;AAAA,EACjC;AACF;AAEA,SAAS,eACP,QACA,IACA,WACA;AAGA,SAAO,IAAI;AAAA,IACT,CAAA;AAAA,IACA;AAAA,MACE,IAAI,QAAgD,MAAc;AAChE,YAAI,QAAQ,QAAQ;AAClB,iBAAO,OAAO,IAAI;AAAA,QACpB;AAEA,eAAO,IAAI,IAAI,cAAc,QAAQ,MAAM,IAAI,SAAS;AACxD,eAAO,OAAO,IAAI;AAAA,MACpB;AAAA,IAAA;AAAA,EACF;AAEJ;AAEA,SAAS,sBAAsB,SAAuC;AAEpE;AAAA,IACE,SAAS,SAAS;AAAA,IAClB;AAAA,EAAA;AAEJ;AAEA,SAAS,eAAe,IAAgB,WAA4B;AAClE,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAoB,iBAAA;AAAA,IACpB;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,SAAS,cACP,QACA,WACA,IACA,WACA;AACA,QAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,CAAC;AAC3C,QAAM,EAAC,eAAc;AACrB,SAAO;AAAA,IACL,QAAQ,CAAC,UACP;AAAA,MACE;AAAA,MACA,EAAe,WAAuB,MAAA;AAAA,MACtC;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,QAAQ,CAAC,UACP;AAAA,MACE;AAAA,MACA,EAAC,IAAI,UAAU,WAAW,YAAY,MAAA;AAAA,MACtC;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,QAAQ,CAAC,UACP;AAAA,MACE;AAAA,MACA,EAAe,WAAuB,MAAA;AAAA,MACtC;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,QAAQ,CAAC,OACP;AAAA,MACE;AAAA,MACA,EAAe,WAAuB,OAAO,GAAA;AAAA,MAC7C;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAEN;"}
|
|
@@ -31,6 +31,11 @@ export type OfflineError = ClientError<{
|
|
|
31
31
|
kind: ClientErrorKind.Offline;
|
|
32
32
|
message: string;
|
|
33
33
|
}>;
|
|
34
|
+
export type NoSocketOriginError = ClientError<{
|
|
35
|
+
kind: ClientErrorKind.NoSocketOrigin;
|
|
36
|
+
message: string;
|
|
37
|
+
}>;
|
|
38
|
+
export type DisconnectedReason = OfflineError | NoSocketOriginError;
|
|
34
39
|
export type ServerError = ProtocolError<ErrorBody>;
|
|
35
40
|
export type ZeroError = ServerError | ClientError;
|
|
36
41
|
export type ZeroErrorBody = Expand<ErrorBody | ClientErrorBody>;
|
|
@@ -64,7 +69,7 @@ export type ErrorConnectionTransition = {
|
|
|
64
69
|
reason: ZeroError;
|
|
65
70
|
} | {
|
|
66
71
|
status: ConnectionStatus.Disconnected;
|
|
67
|
-
reason:
|
|
72
|
+
reason: DisconnectedReason;
|
|
68
73
|
} | {
|
|
69
74
|
status: ConnectionStatus.Closed;
|
|
70
75
|
reason: ZeroError;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/error.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/client/error.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { MutationFailed, MutationRateLimited, Unauthorized, AuthInvalidated, Ser
|
|
|
4
4
|
import { Client, Server, ZeroCache } from "../../../zero-protocol/src/error-origin-enum.js";
|
|
5
5
|
import { HTTP } from "../../../zero-protocol/src/error-reason-enum.js";
|
|
6
6
|
import { isProtocolError } from "../../../zero-protocol/src/error.js";
|
|
7
|
-
import { ClientClosed, Offline, UserDisconnect, InvalidMessage, Internal, UnexpectedBaseCookie,
|
|
7
|
+
import { ClientClosed, NoSocketOrigin, Offline, UserDisconnect, InvalidMessage, Internal, UnexpectedBaseCookie, Hidden, PullTimeout, PingTimeout, ConnectTimeout, CleanClose, AbruptClose } from "./client-error-kind-enum.js";
|
|
8
8
|
import { NeedsAuth, Closed, Disconnected, Error as Error$1 } from "./connection-status-enum.js";
|
|
9
9
|
class ClientError extends Error {
|
|
10
10
|
errorBody;
|
|
@@ -65,7 +65,6 @@ function getErrorConnectionTransition(ex) {
|
|
|
65
65
|
case PingTimeout:
|
|
66
66
|
case PullTimeout:
|
|
67
67
|
case Hidden:
|
|
68
|
-
case NoSocketOrigin:
|
|
69
68
|
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
70
69
|
// Fatal errors that should transition to error state
|
|
71
70
|
case UnexpectedBaseCookie:
|
|
@@ -75,6 +74,7 @@ function getErrorConnectionTransition(ex) {
|
|
|
75
74
|
return { status: Error$1, reason: ex };
|
|
76
75
|
// Disconnected error (this should already result in a disconnected state)
|
|
77
76
|
case Offline:
|
|
77
|
+
case NoSocketOrigin:
|
|
78
78
|
return {
|
|
79
79
|
status: Disconnected,
|
|
80
80
|
reason: ex
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sources":["../../../../../zero-client/src/client/error.ts"],"sourcesContent":["import {unreachable} from '../../../shared/src/asserts.ts';\nimport {getErrorMessage} from '../../../shared/src/error.ts';\nimport type {Expand} from '../../../shared/src/expand.ts';\nimport {ErrorKind} from '../../../zero-protocol/src/error-kind.ts';\nimport {ErrorOrigin} from '../../../zero-protocol/src/error-origin.ts';\nimport {ErrorReason} from '../../../zero-protocol/src/error-reason.ts';\nimport type {ProtocolError} from '../../../zero-protocol/src/error.ts';\nimport {\n type BackoffBody,\n type ErrorBody,\n isProtocolError,\n type PushFailedBody,\n type TransformFailedBody,\n} from '../../../zero-protocol/src/error.ts';\nimport {ClientErrorKind} from './client-error-kind.ts';\nimport {ConnectionStatus} from './connection-status.ts';\n\nexport type AuthError = ProtocolError<NeedsAuthReason>;\nexport type ClientErrorBody = {\n kind: ClientErrorKind;\n origin: typeof ErrorOrigin.Client;\n message: string;\n};\nexport type ClosedError = ClientError<{\n kind: ClientErrorKind.ClientClosed;\n message: string;\n}>;\nexport type NeedsAuthReason = Expand<\n | (ErrorBody & {\n kind: ErrorKind.AuthInvalidated | ErrorKind.Unauthorized;\n })\n | (Extract<PushFailedBody, {reason: ErrorReason.HTTP}> & {status: 401 | 403})\n | (Extract<TransformFailedBody, {reason: ErrorReason.HTTP}> & {\n status: 401 | 403;\n })\n>;\nexport type OfflineError = ClientError<{\n kind: ClientErrorKind.Offline;\n message: string;\n}>;\nexport type ServerError = ProtocolError<ErrorBody>;\nexport type ZeroError = ServerError | ClientError;\nexport type ZeroErrorBody = Expand<ErrorBody | ClientErrorBody>;\nexport type ZeroErrorDetails = Expand<Omit<ZeroErrorBody, 'message'>>;\nexport type ZeroErrorKind = Expand<ErrorKind | ClientErrorKind>;\n\n/**\n * Represents an error encountered by the Zero client.\n */\nexport class ClientError<\n const T extends Omit<ClientErrorBody, 'origin'> = Omit<\n ClientErrorBody,\n 'origin'\n >,\n> extends Error {\n readonly errorBody: {origin: typeof ErrorOrigin.Client} & T;\n\n constructor(errorBody: T, options?: ErrorOptions) {\n super(errorBody.message, options);\n this.name = 'ClientError';\n this.errorBody = {...errorBody, origin: ErrorOrigin.Client};\n }\n\n get kind(): T['kind'] {\n return this.errorBody.kind;\n }\n}\n\nexport function isZeroError(ex: unknown): ex is ZeroError {\n return isClientError(ex) || isServerError(ex);\n}\n\nexport function isClientError(ex: unknown): ex is ClientError<ClientErrorBody> {\n return (\n ex instanceof ClientError && ex.errorBody.origin === ErrorOrigin.Client\n );\n}\n\nexport function isServerError(ex: unknown): ex is ServerError {\n return (\n isProtocolError(ex) &&\n (ex.errorBody.origin === ErrorOrigin.Server ||\n ex.errorBody.origin === ErrorOrigin.ZeroCache)\n );\n}\n\nexport function isOfflineError(ex: unknown): ex is OfflineError {\n return isClientError(ex) && ex.kind === ClientErrorKind.Offline;\n}\n\nexport function isAuthError(ex: unknown): ex is AuthError {\n if (isServerError(ex)) {\n if (\n ex.kind === ErrorKind.AuthInvalidated ||\n ex.kind === ErrorKind.Unauthorized\n ) {\n return true;\n }\n if (\n (ex.errorBody.kind === ErrorKind.PushFailed ||\n ex.errorBody.kind === ErrorKind.TransformFailed) &&\n ex.errorBody.reason === ErrorReason.HTTP &&\n (ex.errorBody.status === 401 || ex.errorBody.status === 403)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function getBackoffParams(error: ZeroError): BackoffBody | undefined {\n if (isServerError(error)) {\n switch (error.errorBody.kind) {\n case ErrorKind.Rebalance:\n case ErrorKind.Rehome:\n case ErrorKind.ServerOverloaded:\n return error.errorBody;\n }\n }\n return undefined;\n}\n\nexport const NO_STATUS_TRANSITION = 'NO_STATUS_TRANSITION';\n\nexport type ErrorConnectionTransition =\n | {status: typeof NO_STATUS_TRANSITION; reason: ZeroError}\n | {status: ConnectionStatus.NeedsAuth; reason: AuthError}\n | {status: ConnectionStatus.Error; reason: ZeroError}\n | {status: ConnectionStatus.Disconnected; reason: OfflineError}\n | {status: ConnectionStatus.Closed; reason: ZeroError};\n\n/**\n * Returns the status to transition to, or null if the error\n * indicates that the connection should continue in the current state.\n */\nexport function getErrorConnectionTransition(\n ex: unknown,\n): ErrorConnectionTransition {\n // Handle auth errors by transitioning to needs-auth state\n if (isAuthError(ex)) {\n return {\n status: ConnectionStatus.NeedsAuth,\n reason: ex,\n } as const;\n }\n\n if (isClientError(ex)) {\n switch (ex.kind) {\n // Connecting errors that should continue in the current state\n case ClientErrorKind.AbruptClose:\n case ClientErrorKind.CleanClose:\n case ClientErrorKind.ConnectTimeout:\n case ClientErrorKind.PingTimeout:\n case ClientErrorKind.PullTimeout:\n case ClientErrorKind.Hidden:\n case ClientErrorKind.NoSocketOrigin:\n return {status: NO_STATUS_TRANSITION, reason: ex} as const;\n\n // Fatal errors that should transition to error state\n case ClientErrorKind.UnexpectedBaseCookie:\n case ClientErrorKind.Internal:\n case ClientErrorKind.InvalidMessage:\n case ClientErrorKind.UserDisconnect:\n return {status: ConnectionStatus.Error, reason: ex} as const;\n\n // Disconnected error (this should already result in a disconnected state)\n case ClientErrorKind.Offline:\n return {\n status: ConnectionStatus.Disconnected,\n reason: ex as OfflineError,\n } as const;\n\n // Closed error (this should already result in a closed state)\n case ClientErrorKind.ClientClosed:\n return {status: ConnectionStatus.Closed, reason: ex} as const;\n\n default:\n unreachable(ex.kind);\n }\n }\n\n if (isServerError(ex)) {\n switch (ex.kind) {\n // Errors that should transition to error state\n case ErrorKind.ClientNotFound:\n case ErrorKind.InvalidConnectionRequest:\n case ErrorKind.InvalidConnectionRequestBaseCookie:\n case ErrorKind.InvalidConnectionRequestLastMutationID:\n case ErrorKind.InvalidConnectionRequestClientDeleted:\n case ErrorKind.InvalidMessage:\n case ErrorKind.InvalidPush:\n case ErrorKind.VersionNotSupported:\n case ErrorKind.SchemaVersionNotSupported:\n case ErrorKind.Internal:\n // PushFailed and TransformFailed can be auth errors (401/403)\n // or other errors - handle non-auth cases here\n case ErrorKind.PushFailed:\n case ErrorKind.TransformFailed:\n return {status: ConnectionStatus.Error, reason: ex} as const;\n\n // Errors that should continue with backoff/retry\n case ErrorKind.Rebalance:\n case ErrorKind.Rehome:\n case ErrorKind.ServerOverloaded:\n return {status: NO_STATUS_TRANSITION, reason: ex} as const;\n\n // Auth errors are handled above by isAuthError check\n case ErrorKind.AuthInvalidated:\n case ErrorKind.Unauthorized:\n return {\n status: ConnectionStatus.NeedsAuth,\n reason: ex as AuthError,\n } as const;\n\n // Mutation-specific errors don't affect connection state\n case ErrorKind.MutationRateLimited:\n case ErrorKind.MutationFailed:\n return {status: NO_STATUS_TRANSITION, reason: ex} as const;\n\n default:\n unreachable(ex.kind);\n }\n }\n\n // we default to error state if we don't know what to do\n // this is a catch-all for unexpected errors\n return {\n status: ConnectionStatus.Error,\n reason: new ClientError(\n {\n kind: ClientErrorKind.Internal,\n message: 'Unexpected internal error: ' + getErrorMessage(ex),\n },\n {cause: ex},\n ),\n } as const;\n}\n"],"names":["ErrorOrigin.Client","ErrorOrigin.Server","ErrorOrigin.ZeroCache","ErrorKind.AuthInvalidated","ErrorKind.Unauthorized","ErrorKind.PushFailed","ErrorKind.TransformFailed","ErrorReason.HTTP","ErrorKind.Rebalance","ErrorKind.Rehome","ErrorKind.ServerOverloaded","ConnectionStatus.NeedsAuth","ClientErrorKind.AbruptClose","ClientErrorKind.CleanClose","ClientErrorKind.ConnectTimeout","ClientErrorKind.PingTimeout","ClientErrorKind.PullTimeout","ClientErrorKind.Hidden","ClientErrorKind.NoSocketOrigin","ClientErrorKind.UnexpectedBaseCookie","ClientErrorKind.Internal","ClientErrorKind.InvalidMessage","ClientErrorKind.UserDisconnect","ConnectionStatus.Error","ClientErrorKind.Offline","ConnectionStatus.Disconnected","ClientErrorKind.ClientClosed","ConnectionStatus.Closed","ErrorKind.ClientNotFound","ErrorKind.InvalidConnectionRequest","ErrorKind.InvalidConnectionRequestBaseCookie","ErrorKind.InvalidConnectionRequestLastMutationID","ErrorKind.InvalidConnectionRequestClientDeleted","ErrorKind.InvalidMessage","ErrorKind.InvalidPush","ErrorKind.VersionNotSupported","ErrorKind.SchemaVersionNotSupported","ErrorKind.Internal","ErrorKind.MutationRateLimited","ErrorKind.MutationFailed"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"error.js","sources":["../../../../../zero-client/src/client/error.ts"],"sourcesContent":["import {unreachable} from '../../../shared/src/asserts.ts';\nimport {getErrorMessage} from '../../../shared/src/error.ts';\nimport type {Expand} from '../../../shared/src/expand.ts';\nimport {ErrorKind} from '../../../zero-protocol/src/error-kind.ts';\nimport {ErrorOrigin} from '../../../zero-protocol/src/error-origin.ts';\nimport {ErrorReason} from '../../../zero-protocol/src/error-reason.ts';\nimport type {ProtocolError} from '../../../zero-protocol/src/error.ts';\nimport {\n type BackoffBody,\n type ErrorBody,\n isProtocolError,\n type PushFailedBody,\n type TransformFailedBody,\n} from '../../../zero-protocol/src/error.ts';\nimport {ClientErrorKind} from './client-error-kind.ts';\nimport {ConnectionStatus} from './connection-status.ts';\n\nexport type AuthError = ProtocolError<NeedsAuthReason>;\nexport type ClientErrorBody = {\n kind: ClientErrorKind;\n origin: typeof ErrorOrigin.Client;\n message: string;\n};\nexport type ClosedError = ClientError<{\n kind: ClientErrorKind.ClientClosed;\n message: string;\n}>;\nexport type NeedsAuthReason = Expand<\n | (ErrorBody & {\n kind: ErrorKind.AuthInvalidated | ErrorKind.Unauthorized;\n })\n | (Extract<PushFailedBody, {reason: ErrorReason.HTTP}> & {status: 401 | 403})\n | (Extract<TransformFailedBody, {reason: ErrorReason.HTTP}> & {\n status: 401 | 403;\n })\n>;\nexport type OfflineError = ClientError<{\n kind: ClientErrorKind.Offline;\n message: string;\n}>;\nexport type NoSocketOriginError = ClientError<{\n kind: ClientErrorKind.NoSocketOrigin;\n message: string;\n}>;\nexport type DisconnectedReason = OfflineError | NoSocketOriginError;\nexport type ServerError = ProtocolError<ErrorBody>;\nexport type ZeroError = ServerError | ClientError;\nexport type ZeroErrorBody = Expand<ErrorBody | ClientErrorBody>;\nexport type ZeroErrorDetails = Expand<Omit<ZeroErrorBody, 'message'>>;\nexport type ZeroErrorKind = Expand<ErrorKind | ClientErrorKind>;\n\n/**\n * Represents an error encountered by the Zero client.\n */\nexport class ClientError<\n const T extends Omit<ClientErrorBody, 'origin'> = Omit<\n ClientErrorBody,\n 'origin'\n >,\n> extends Error {\n readonly errorBody: {origin: typeof ErrorOrigin.Client} & T;\n\n constructor(errorBody: T, options?: ErrorOptions) {\n super(errorBody.message, options);\n this.name = 'ClientError';\n this.errorBody = {...errorBody, origin: ErrorOrigin.Client};\n }\n\n get kind(): T['kind'] {\n return this.errorBody.kind;\n }\n}\n\nexport function isZeroError(ex: unknown): ex is ZeroError {\n return isClientError(ex) || isServerError(ex);\n}\n\nexport function isClientError(ex: unknown): ex is ClientError<ClientErrorBody> {\n return (\n ex instanceof ClientError && ex.errorBody.origin === ErrorOrigin.Client\n );\n}\n\nexport function isServerError(ex: unknown): ex is ServerError {\n return (\n isProtocolError(ex) &&\n (ex.errorBody.origin === ErrorOrigin.Server ||\n ex.errorBody.origin === ErrorOrigin.ZeroCache)\n );\n}\n\nexport function isOfflineError(ex: unknown): ex is OfflineError {\n return isClientError(ex) && ex.kind === ClientErrorKind.Offline;\n}\n\nexport function isAuthError(ex: unknown): ex is AuthError {\n if (isServerError(ex)) {\n if (\n ex.kind === ErrorKind.AuthInvalidated ||\n ex.kind === ErrorKind.Unauthorized\n ) {\n return true;\n }\n if (\n (ex.errorBody.kind === ErrorKind.PushFailed ||\n ex.errorBody.kind === ErrorKind.TransformFailed) &&\n ex.errorBody.reason === ErrorReason.HTTP &&\n (ex.errorBody.status === 401 || ex.errorBody.status === 403)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function getBackoffParams(error: ZeroError): BackoffBody | undefined {\n if (isServerError(error)) {\n switch (error.errorBody.kind) {\n case ErrorKind.Rebalance:\n case ErrorKind.Rehome:\n case ErrorKind.ServerOverloaded:\n return error.errorBody;\n }\n }\n return undefined;\n}\n\nexport const NO_STATUS_TRANSITION = 'NO_STATUS_TRANSITION';\n\nexport type ErrorConnectionTransition =\n | {status: typeof NO_STATUS_TRANSITION; reason: ZeroError}\n | {status: ConnectionStatus.NeedsAuth; reason: AuthError}\n | {status: ConnectionStatus.Error; reason: ZeroError}\n | {status: ConnectionStatus.Disconnected; reason: DisconnectedReason}\n | {status: ConnectionStatus.Closed; reason: ZeroError};\n\n/**\n * Returns the status to transition to, or null if the error\n * indicates that the connection should continue in the current state.\n */\nexport function getErrorConnectionTransition(\n ex: unknown,\n): ErrorConnectionTransition {\n // Handle auth errors by transitioning to needs-auth state\n if (isAuthError(ex)) {\n return {\n status: ConnectionStatus.NeedsAuth,\n reason: ex,\n } as const;\n }\n\n if (isClientError(ex)) {\n switch (ex.kind) {\n // Connecting errors that should continue in the current state\n case ClientErrorKind.AbruptClose:\n case ClientErrorKind.CleanClose:\n case ClientErrorKind.ConnectTimeout:\n case ClientErrorKind.PingTimeout:\n case ClientErrorKind.PullTimeout:\n case ClientErrorKind.Hidden:\n return {status: NO_STATUS_TRANSITION, reason: ex} as const;\n\n // Fatal errors that should transition to error state\n case ClientErrorKind.UnexpectedBaseCookie:\n case ClientErrorKind.Internal:\n case ClientErrorKind.InvalidMessage:\n case ClientErrorKind.UserDisconnect:\n return {status: ConnectionStatus.Error, reason: ex} as const;\n\n // Disconnected error (this should already result in a disconnected state)\n case ClientErrorKind.Offline:\n case ClientErrorKind.NoSocketOrigin:\n return {\n status: ConnectionStatus.Disconnected,\n reason: ex as DisconnectedReason,\n } as const;\n\n // Closed error (this should already result in a closed state)\n case ClientErrorKind.ClientClosed:\n return {status: ConnectionStatus.Closed, reason: ex} as const;\n\n default:\n unreachable(ex.kind);\n }\n }\n\n if (isServerError(ex)) {\n switch (ex.kind) {\n // Errors that should transition to error state\n case ErrorKind.ClientNotFound:\n case ErrorKind.InvalidConnectionRequest:\n case ErrorKind.InvalidConnectionRequestBaseCookie:\n case ErrorKind.InvalidConnectionRequestLastMutationID:\n case ErrorKind.InvalidConnectionRequestClientDeleted:\n case ErrorKind.InvalidMessage:\n case ErrorKind.InvalidPush:\n case ErrorKind.VersionNotSupported:\n case ErrorKind.SchemaVersionNotSupported:\n case ErrorKind.Internal:\n // PushFailed and TransformFailed can be auth errors (401/403)\n // or other errors - handle non-auth cases here\n case ErrorKind.PushFailed:\n case ErrorKind.TransformFailed:\n return {status: ConnectionStatus.Error, reason: ex} as const;\n\n // Errors that should continue with backoff/retry\n case ErrorKind.Rebalance:\n case ErrorKind.Rehome:\n case ErrorKind.ServerOverloaded:\n return {status: NO_STATUS_TRANSITION, reason: ex} as const;\n\n // Auth errors are handled above by isAuthError check\n case ErrorKind.AuthInvalidated:\n case ErrorKind.Unauthorized:\n return {\n status: ConnectionStatus.NeedsAuth,\n reason: ex as AuthError,\n } as const;\n\n // Mutation-specific errors don't affect connection state\n case ErrorKind.MutationRateLimited:\n case ErrorKind.MutationFailed:\n return {status: NO_STATUS_TRANSITION, reason: ex} as const;\n\n default:\n unreachable(ex.kind);\n }\n }\n\n // we default to error state if we don't know what to do\n // this is a catch-all for unexpected errors\n return {\n status: ConnectionStatus.Error,\n reason: new ClientError(\n {\n kind: ClientErrorKind.Internal,\n message: 'Unexpected internal error: ' + getErrorMessage(ex),\n },\n {cause: ex},\n ),\n } as const;\n}\n"],"names":["ErrorOrigin.Client","ErrorOrigin.Server","ErrorOrigin.ZeroCache","ErrorKind.AuthInvalidated","ErrorKind.Unauthorized","ErrorKind.PushFailed","ErrorKind.TransformFailed","ErrorReason.HTTP","ErrorKind.Rebalance","ErrorKind.Rehome","ErrorKind.ServerOverloaded","ConnectionStatus.NeedsAuth","ClientErrorKind.AbruptClose","ClientErrorKind.CleanClose","ClientErrorKind.ConnectTimeout","ClientErrorKind.PingTimeout","ClientErrorKind.PullTimeout","ClientErrorKind.Hidden","ClientErrorKind.UnexpectedBaseCookie","ClientErrorKind.Internal","ClientErrorKind.InvalidMessage","ClientErrorKind.UserDisconnect","ConnectionStatus.Error","ClientErrorKind.Offline","ClientErrorKind.NoSocketOrigin","ConnectionStatus.Disconnected","ClientErrorKind.ClientClosed","ConnectionStatus.Closed","ErrorKind.ClientNotFound","ErrorKind.InvalidConnectionRequest","ErrorKind.InvalidConnectionRequestBaseCookie","ErrorKind.InvalidConnectionRequestLastMutationID","ErrorKind.InvalidConnectionRequestClientDeleted","ErrorKind.InvalidMessage","ErrorKind.InvalidPush","ErrorKind.VersionNotSupported","ErrorKind.SchemaVersionNotSupported","ErrorKind.Internal","ErrorKind.MutationRateLimited","ErrorKind.MutationFailed"],"mappings":"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"}
|