@securitydept/client 0.3.0-beta.1 → 0.3.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/create-i5VyYgN6.mjs +989 -0
- package/dist/create-i5VyYgN6.mjs.map +1 -0
- package/dist/handle-DwMgqe7R.mjs +638 -0
- package/dist/handle-DwMgqe7R.mjs.map +1 -0
- package/dist/index-Bo1BtjZH.d.mts +132 -0
- package/dist/index-CFAJ969E.d.mts +674 -0
- package/dist/index-CbeZ3AfB.d.mts +1680 -0
- package/dist/index.d.mts +3 -353
- package/dist/index.mjs +1196 -401
- package/dist/index.mjs.map +1 -1
- package/dist/router-at5bTdJQ.mjs +245 -0
- package/dist/router-at5bTdJQ.mjs.map +1 -0
- package/dist/rx/index.d.mts +68 -0
- package/dist/rx/index.mjs +2 -0
- package/dist/rx-DM6Ouv-m.mjs +1119 -0
- package/dist/rx-DM6Ouv-m.mjs.map +1 -0
- package/dist/server/index.d.mts +20 -0
- package/dist/server/index.mjs +29 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/test/index.d.mts +101 -0
- package/dist/test/index.mjs +270 -0
- package/dist/test/index.mjs.map +1 -0
- package/dist/uri-string-BPNbIMgv.mjs +300 -0
- package/dist/uri-string-BPNbIMgv.mjs.map +1 -0
- package/dist/web/index.d.mts +82 -337
- package/dist/web/index.mjs +334 -337
- package/dist/web/index.mjs.map +1 -1
- package/dist/webext/index.d.mts +73 -0
- package/dist/webext/index.mjs +231 -0
- package/dist/webext/index.mjs.map +1 -0
- package/package.json +28 -21
- package/dist/auth-coordination/index.d.mts +0 -198
- package/dist/auth-coordination/index.mjs +0 -107
- package/dist/auth-coordination/index.mjs.map +0 -1
- package/dist/events/index.d.mts +0 -2
- package/dist/events/index.mjs +0 -2
- package/dist/events-BUlfsRfl.mjs +0 -127
- package/dist/events-BUlfsRfl.mjs.map +0 -1
- package/dist/fetch-transport-Bd5RyWj2.d.mts +0 -339
- package/dist/fetch-transport-DtnSRWAH.mjs +0 -631
- package/dist/fetch-transport-DtnSRWAH.mjs.map +0 -1
- package/dist/index-C_wgl6dW.d.mts +0 -102
- package/dist/index-DbYSFHDe.d.mts +0 -39
- package/dist/persistence/index.d.mts +0 -3
- package/dist/persistence/index.mjs +0 -2
- package/dist/persistence/web/index.d.mts +0 -16
- package/dist/persistence/web/index.mjs +0 -51
- package/dist/persistence/web/index.mjs.map +0 -1
- package/dist/persistence-CSB8770k.mjs +0 -108
- package/dist/persistence-CSB8770k.mjs.map +0 -1
- package/dist/planner-host-CPyGNyQV.d.mts +0 -190
- package/dist/planner-host-CV38bMSn.mjs +0 -195
- package/dist/planner-host-CV38bMSn.mjs.map +0 -1
- package/dist/types-C59fcM5W.d.mts +0 -52
- package/dist/types-DQc088ZP.d.mts +0 -32
- package/dist/web-router/index.d.mts +0 -259
- package/dist/web-router/index.mjs +0 -395
- package/dist/web-router/index.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-transport-DtnSRWAH.mjs","names":[],"sources":["../src/errors/types.ts","../src/errors/client-error.ts","../src/logging/types.ts","../src/logging/operation-tracer.ts","../src/scheduling/default-clock.ts","../src/scheduling/default-scheduler.ts","../src/runtime/create-runtime.ts","../src/scheduling/helpers.ts","../src/web/input-sources.ts","../src/web/cancellation.ts","../src/transport/fetch-transport.ts"],"sourcesContent":["// --- Error model ---\n// Dual-layer: machine-facing runtime error + user-facing presentation / recovery hint.\n\n/** Recovery actions the user might take. Aligned with server-side `UserRecovery`. */\nexport const UserRecovery = {\n\tNone: \"none\",\n\tRetry: \"retry\",\n\tRestartFlow: \"restart_flow\",\n\tReauthenticate: \"reauthenticate\",\n\tContactSupport: \"contact_support\",\n} as const;\n\nexport type UserRecovery = (typeof UserRecovery)[keyof typeof UserRecovery];\n\n/** User-facing error presentation. `code` is the cross-platform stable contract. */\nexport interface ErrorPresentation {\n\tcode: string;\n\tmessage: string;\n\trecovery: UserRecovery;\n}\n\nexport const ErrorPresentationTone = {\n\tNeutral: \"neutral\",\n\tWarning: \"warning\",\n\tDanger: \"danger\",\n} as const;\n\nexport type ErrorPresentationTone =\n\t(typeof ErrorPresentationTone)[keyof typeof ErrorPresentationTone];\n\nexport interface ErrorPresentationActionDescriptor {\n\trecovery: UserRecovery;\n\tlabel: string;\n\thref: string | null;\n}\n\nexport interface ErrorPresentationDescriptor {\n\tcode: string | null;\n\tkind: ClientErrorKind | null;\n\tsource?: string;\n\ttitle: string;\n\tdescription: string;\n\trecovery: UserRecovery;\n\tretryable: boolean;\n\ttone: ErrorPresentationTone;\n\tprimaryAction: ErrorPresentationActionDescriptor | null;\n}\n\nexport interface ReadErrorPresentationDescriptorOptions {\n\tfallbackTitle?: string;\n\tfallbackDescription?: string;\n\trecoveryLinks?: Partial<Record<UserRecovery, string>>;\n\trecoveryLabels?: Partial<Record<UserRecovery, string>>;\n}\n\n/** Machine-facing error kind discriminator. */\nexport const ClientErrorKind = {\n\tAuthorization: \"authorization\",\n\tTransport: \"transport\",\n\tServer: \"server\",\n\tProtocol: \"protocol\",\n\tPresentation: \"presentation\",\n\tValidation: \"validation\",\n\tStorage: \"storage\",\n\tScheduler: \"scheduler\",\n\tConfiguration: \"configuration\",\n\tUnauthenticated: \"unauthenticated\",\n\tUnauthorized: \"unauthorized\",\n\tRedirectRequired: \"redirect_required\",\n\tCancelled: \"cancelled\",\n\tTimeout: \"timeout\",\n\tInternal: \"internal\",\n} as const;\n\nexport type ClientErrorKind =\n\t(typeof ClientErrorKind)[keyof typeof ClientErrorKind];\n\n/** Stable source vocabulary for common client error producers. */\nexport const ClientErrorSource = {\n\tTransport: \"transport\",\n\tServer: \"server\",\n\tClientRuntime: \"client_runtime\",\n} as const;\n\nexport type ClientErrorSource =\n\t(typeof ClientErrorSource)[keyof typeof ClientErrorSource];\n","import {\n\tClientErrorKind,\n\tClientErrorSource,\n\ttype ErrorPresentation,\n\tUserRecovery,\n\ttype UserRecovery as UserRecoveryType,\n} from \"./types\";\n\ntype ServerErrorBody = {\n\tkind?: string;\n\tcode?: string;\n\tmessage?: string;\n\trecovery?: string;\n\tpresentation?: {\n\t\tcode?: string;\n\t\tmessage?: string;\n\t\trecovery?: string;\n\t};\n};\n\nfunction mapServerErrorKind(\n\tkind: string | undefined,\n\tstatus: number,\n): ClientErrorKind {\n\tswitch (kind) {\n\t\tcase \"unauthenticated\":\n\t\t\treturn ClientErrorKind.Unauthenticated;\n\t\tcase \"unauthorized\":\n\t\t\treturn ClientErrorKind.Unauthorized;\n\t\tcase \"unavailable\":\n\t\tcase \"internal\":\n\t\t\treturn ClientErrorKind.Server;\n\t\tcase \"invalid_request\":\n\t\tcase \"conflict\":\n\t\t\treturn ClientErrorKind.Protocol;\n\t\tdefault:\n\t\t\treturn status === 401\n\t\t\t\t? ClientErrorKind.Unauthenticated\n\t\t\t\t: status === 403\n\t\t\t\t\t? ClientErrorKind.Unauthorized\n\t\t\t\t\t: status >= 500\n\t\t\t\t\t\t? ClientErrorKind.Server\n\t\t\t\t\t\t: ClientErrorKind.Protocol;\n\t}\n}\n\nfunction readServerErrorBody(body: unknown): ServerErrorBody | undefined {\n\tif (!body || typeof body !== \"object\") return undefined;\n\tconst record = body as Record<string, unknown>;\n\tconst error =\n\t\trecord.error && typeof record.error === \"object\"\n\t\t\t? (record.error as Record<string, unknown>)\n\t\t\t: record;\n\n\treturn {\n\t\tkind: typeof error.kind === \"string\" ? error.kind : undefined,\n\t\tcode: typeof error.code === \"string\" ? error.code : undefined,\n\t\tmessage: typeof error.message === \"string\" ? error.message : undefined,\n\t\trecovery: typeof error.recovery === \"string\" ? error.recovery : undefined,\n\t\tpresentation:\n\t\t\terror.presentation && typeof error.presentation === \"object\"\n\t\t\t\t? {\n\t\t\t\t\t\tcode:\n\t\t\t\t\t\t\ttypeof (error.presentation as Record<string, unknown>).code ===\n\t\t\t\t\t\t\t\"string\"\n\t\t\t\t\t\t\t\t? ((error.presentation as Record<string, unknown>)\n\t\t\t\t\t\t\t\t\t\t.code as string)\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\ttypeof (error.presentation as Record<string, unknown>).message ===\n\t\t\t\t\t\t\t\"string\"\n\t\t\t\t\t\t\t\t? ((error.presentation as Record<string, unknown>)\n\t\t\t\t\t\t\t\t\t\t.message as string)\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\trecovery:\n\t\t\t\t\t\t\ttypeof (error.presentation as Record<string, unknown>)\n\t\t\t\t\t\t\t\t.recovery === \"string\"\n\t\t\t\t\t\t\t\t? ((error.presentation as Record<string, unknown>)\n\t\t\t\t\t\t\t\t\t\t.recovery as string)\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t};\n}\n\n/**\n * Base client error carrying both machine-facing context and an optional\n * user-facing presentation layer.\n *\n * Top-level `code` and `recovery` provide stable machine contracts for\n * policy decisions without requiring callers to unwrap `presentation`.\n */\nexport class ClientError extends Error {\n\treadonly kind: ClientErrorKind;\n\n\t/**\n\t * Stable machine-readable error code.\n\t * Matches `presentation.code` when present, otherwise a default\n\t * derived from `kind`.\n\t */\n\treadonly code: string;\n\n\t/** Recovery hint at the machine level. */\n\treadonly recovery: UserRecoveryType;\n\n\t/** Whether this error is safe to retry. */\n\treadonly retryable: boolean;\n\n\t/** Structured user-facing error presentation from the server. */\n\treadonly presentation?: ErrorPresentation;\n\n\t/** Source subsystem or component that produced the error. */\n\treadonly source?: string;\n\n\tconstructor(options: {\n\t\tkind: ClientErrorKind;\n\t\tmessage: string;\n\t\tcode?: string;\n\t\trecovery?: UserRecoveryType;\n\t\tretryable?: boolean;\n\t\tpresentation?: ErrorPresentation;\n\t\tsource?: string;\n\t\tcause?: unknown;\n\t}) {\n\t\tsuper(options.message, { cause: options.cause });\n\t\tthis.name = \"ClientError\";\n\t\tthis.kind = options.kind;\n\t\tthis.code =\n\t\t\toptions.code ?? options.presentation?.code ?? `client.${options.kind}`;\n\t\tthis.recovery =\n\t\t\toptions.recovery ?? options.presentation?.recovery ?? UserRecovery.None;\n\t\tthis.retryable = options.retryable ?? this.recovery === UserRecovery.Retry;\n\t\tthis.presentation = options.presentation;\n\t\tthis.source = options.source;\n\t}\n\n\t/** Create a `ClientError` from a server error response body. */\n\tstatic fromServerError(\n\t\tbody: {\n\t\t\tkind?: string;\n\t\t\tcode?: string;\n\t\t\tmessage?: string;\n\t\t\trecovery?: string;\n\t\t\tpresentation?: {\n\t\t\t\tcode?: string;\n\t\t\t\tmessage?: string;\n\t\t\t\trecovery?: string;\n\t\t\t};\n\t\t},\n\t\toverrides?: { kind?: ClientErrorKind; source?: string },\n\t): ClientError {\n\t\tconst rawPresentation = body.presentation;\n\t\tconst presentation: ErrorPresentation | undefined =\n\t\t\t(rawPresentation?.code ?? body.code) &&\n\t\t\t(rawPresentation?.message ?? body.message)\n\t\t\t\t? {\n\t\t\t\t\t\tcode: rawPresentation?.code ?? body.code ?? \"unknown_server_error\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\trawPresentation?.message ??\n\t\t\t\t\t\t\tbody.message ??\n\t\t\t\t\t\t\t\"Unknown server error\",\n\t\t\t\t\t\trecovery:\n\t\t\t\t\t\t\t(rawPresentation?.recovery as ErrorPresentation[\"recovery\"]) ??\n\t\t\t\t\t\t\t(body.recovery as ErrorPresentation[\"recovery\"]) ??\n\t\t\t\t\t\t\tUserRecovery.None,\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\n\t\treturn new ClientError({\n\t\t\tkind: overrides?.kind ?? mapServerErrorKind(body.kind, 400),\n\t\t\tmessage: presentation?.message ?? body.message ?? \"Unknown server error\",\n\t\t\tpresentation,\n\t\t\tsource: overrides?.source,\n\t\t});\n\t}\n\n\t/**\n\t * Create a `ClientError` from an HTTP response status and optional body.\n\t * Used when a non-success status is unexpected.\n\t */\n\tstatic fromHttpResponse(status: number, body?: unknown): ClientError {\n\t\tconst serverBody = readServerErrorBody(body);\n\n\t\t// Derive kind and source from HTTP status first — these apply\n\t\t// whether or not the response carries a structured error body.\n\t\tconst kind = mapServerErrorKind(serverBody?.kind, status);\n\n\t\tconst source =\n\t\t\tstatus >= 500\n\t\t\t\t? ClientErrorSource.Server\n\t\t\t\t: ClientErrorSource.ClientRuntime;\n\n\t\t// If the server returned a structured error body, preserve it\n\t\t// but keep the status-derived kind/source.\n\t\tif (serverBody?.code && serverBody?.message) {\n\t\t\treturn ClientError.fromServerError(serverBody, { kind, source });\n\t\t}\n\n\t\tconst recovery: UserRecoveryType =\n\t\t\tkind === ClientErrorKind.Unauthenticated\n\t\t\t\t? UserRecovery.Reauthenticate\n\t\t\t\t: status >= 500\n\t\t\t\t\t? UserRecovery.Retry\n\t\t\t\t\t: UserRecovery.None;\n\n\t\treturn new ClientError({\n\t\t\tkind,\n\t\t\tmessage: serverBody?.message ?? `HTTP ${status}`,\n\t\t\tcode: serverBody?.code ?? `http.${status}`,\n\t\t\trecovery,\n\t\t\tretryable: status >= 500,\n\t\t\tsource,\n\t\t});\n\t}\n}\n","// --- Logging and observability ---\n\nexport const LogLevel = {\n\tDebug: \"debug\",\n\tInfo: \"info\",\n\tWarn: \"warn\",\n\tError: \"error\",\n} as const;\n\nexport type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];\n\nexport interface LogEntry {\n\tlevel: LogLevel;\n\tmessage: string;\n\tscope?: string;\n\tcode?: string;\n\tattributes?: Record<string, unknown>;\n\terror?: unknown;\n\tat?: number;\n}\n\nexport interface LoggerTrait {\n\tlog(entry: LogEntry): void;\n}\n\nexport const OperationTraceEventType = {\n\tStarted: \"operation.started\",\n\tEvent: \"operation.event\",\n\tError: \"operation.error\",\n\tEnded: \"operation.ended\",\n} as const;\n\nexport type OperationTraceEventType =\n\t(typeof OperationTraceEventType)[keyof typeof OperationTraceEventType];\n\nexport interface TraceEvent {\n\ttype: string;\n\tat: number;\n\tscope?: string;\n\toperationId?: string;\n\tsource?: string;\n\tattributes?: Record<string, unknown>;\n}\n\nexport interface TraceEventSinkTrait {\n\trecord(event: TraceEvent): void;\n}\n\nexport interface OperationScope {\n\tid: string;\n\taddEvent(type: string, attributes?: Record<string, unknown>): void;\n\tsetAttribute(key: string, value: unknown): void;\n\trecordError(error: unknown, attributes?: Record<string, unknown>): void;\n\tend(attributes?: Record<string, unknown>): void;\n}\n\nexport interface OperationTracerTrait {\n\tstartOperation(\n\t\tname: string,\n\t\tattributes?: Record<string, unknown>,\n\t): OperationScope;\n}\n","import type { Clock } from \"../scheduling/types\";\nimport type {\n\tLoggerTrait,\n\tOperationScope,\n\tOperationTracerTrait,\n\tTraceEventSinkTrait,\n} from \"./types\";\nimport { LogLevel, OperationTraceEventType } from \"./types\";\n\nexport interface CreateOperationTracerOptions {\n\ttraceSink?: TraceEventSinkTrait;\n\tlogger?: LoggerTrait;\n\tclock?: Clock;\n\tscope?: string;\n\tsource?: string;\n\tidFactory?: () => string;\n}\n\nconst defaultClock: Clock = {\n\tnow: () => Date.now(),\n};\n\nfunction createDefaultOperationId(): string {\n\treturn `op_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nclass DefaultOperationScope implements OperationScope {\n\treadonly id: string;\n\n\tprivate readonly _attributes: Record<string, unknown>;\n\tprivate _ended = false;\n\n\tconstructor(\n\t\tprivate readonly _name: string,\n\t\tprivate readonly _clock: Clock,\n\t\tprivate readonly _traceSink: TraceEventSinkTrait | undefined,\n\t\tprivate readonly _logger: LoggerTrait | undefined,\n\t\tprivate readonly _scope: string | undefined,\n\t\tprivate readonly _source: string | undefined,\n\t\tidFactory: () => string,\n\t\tattributes?: Record<string, unknown>,\n\t) {\n\t\tthis.id = idFactory();\n\t\tthis._attributes = { ...(attributes ?? {}) };\n\t\tthis._recordTrace(OperationTraceEventType.Started, {\n\t\t\toperationName: this._name,\n\t\t\t...this._attributes,\n\t\t});\n\t}\n\n\taddEvent(type: string, attributes?: Record<string, unknown>): void {\n\t\tthis._recordTrace(OperationTraceEventType.Event, {\n\t\t\toperationName: this._name,\n\t\t\teventType: type,\n\t\t\t...this._attributes,\n\t\t\t...(attributes ?? {}),\n\t\t});\n\t}\n\n\tsetAttribute(key: string, value: unknown): void {\n\t\tthis._attributes[key] = value;\n\t}\n\n\trecordError(error: unknown, attributes?: Record<string, unknown>): void {\n\t\tconst errorAttributes = describeError(error);\n\t\tthis._recordTrace(OperationTraceEventType.Error, {\n\t\t\toperationName: this._name,\n\t\t\t...this._attributes,\n\t\t\t...errorAttributes,\n\t\t\t...(attributes ?? {}),\n\t\t});\n\t\tthis._logger?.log({\n\t\t\tlevel: LogLevel.Error,\n\t\t\tmessage: `Operation failed: ${this._name}`,\n\t\t\tscope: this._scope,\n\t\t\tattributes: {\n\t\t\t\toperationId: this.id,\n\t\t\t\toperationName: this._name,\n\t\t\t\t...this._attributes,\n\t\t\t\t...errorAttributes,\n\t\t\t\t...(attributes ?? {}),\n\t\t\t},\n\t\t\terror,\n\t\t\tat: this._clock.now(),\n\t\t});\n\t}\n\n\tend(attributes?: Record<string, unknown>): void {\n\t\tif (this._ended) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._ended = true;\n\t\tthis._recordTrace(OperationTraceEventType.Ended, {\n\t\t\toperationName: this._name,\n\t\t\t...this._attributes,\n\t\t\t...(attributes ?? {}),\n\t\t});\n\t}\n\n\tprivate _recordTrace(\n\t\ttype: string,\n\t\tattributes?: Record<string, unknown>,\n\t): void {\n\t\tthis._traceSink?.record({\n\t\t\ttype,\n\t\t\tat: this._clock.now(),\n\t\t\tscope: this._scope,\n\t\t\tsource: this._source,\n\t\t\toperationId: this.id,\n\t\t\tattributes,\n\t\t});\n\t}\n}\n\nexport function createOperationTracer(\n\toptions: CreateOperationTracerOptions = {},\n): OperationTracerTrait {\n\tconst clock = options.clock ?? defaultClock;\n\tconst idFactory = options.idFactory ?? createDefaultOperationId;\n\n\treturn {\n\t\tstartOperation(name, attributes) {\n\t\t\treturn new DefaultOperationScope(\n\t\t\t\tname,\n\t\t\t\tclock,\n\t\t\t\toptions.traceSink,\n\t\t\t\toptions.logger,\n\t\t\t\toptions.scope,\n\t\t\t\toptions.source,\n\t\t\t\tidFactory,\n\t\t\t\tattributes,\n\t\t\t);\n\t\t},\n\t};\n}\n\nfunction describeError(error: unknown): Record<string, unknown> {\n\tif (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"name\" in error &&\n\t\t\"message\" in error\n\t) {\n\t\tconst genericError = error as Pick<Error, \"name\" | \"message\">;\n\t\treturn {\n\t\t\terrorName: genericError.name,\n\t\t\terrorMessage: genericError.message,\n\t\t};\n\t}\n\n\treturn { errorValue: String(error) };\n}\n","import type { Clock } from \"./types\";\n\n/** Default clock backed by `Date.now()`. */\nexport function createDefaultClock(): Clock {\n\treturn {\n\t\tnow() {\n\t\t\treturn Date.now();\n\t\t},\n\t};\n}\n","import type { CancelableHandle, Scheduler } from \"./types\";\n\n/** Default scheduler backed by platform `setTimeout`. */\nexport function createDefaultScheduler(): Scheduler {\n\treturn {\n\t\tsetTimeout(delayMs: number, fn: () => void): CancelableHandle {\n\t\t\tconst id = globalThis.setTimeout(fn, delayMs);\n\t\t\treturn {\n\t\t\t\tcancel() {\n\t\t\t\t\tglobalThis.clearTimeout(id);\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n}\n","import { createOperationTracer } from \"../logging/operation-tracer\";\nimport { createDefaultClock } from \"../scheduling/default-clock\";\nimport { createDefaultScheduler } from \"../scheduling/default-scheduler\";\nimport type { HttpTransport } from \"../transport/types\";\nimport type { ClientRuntime } from \"./types\";\n\nexport interface CreateRuntimeOptions\n\textends Partial<Omit<ClientRuntime, \"transport\">> {\n\ttransport: HttpTransport;\n}\n\n/**\n * Create a `ClientRuntime` with non-host-specific defaults filled in for\n * convenience.\n *\n * Host-specific capabilities such as browser `fetch` should be supplied\n * explicitly or composed via adapter-specific helpers such as\n * `@securitydept/client/web`.\n */\nexport function createRuntime(overrides: CreateRuntimeOptions): ClientRuntime {\n\tconst clock = overrides.clock ?? createDefaultClock();\n\tconst traceSink = overrides.traceSink;\n\tconst logger = overrides.logger;\n\n\treturn {\n\t\ttransport: overrides.transport,\n\t\tscheduler: overrides.scheduler ?? createDefaultScheduler(),\n\t\tclock,\n\t\tlogger,\n\t\ttraceSink,\n\t\toperationTracer:\n\t\t\toverrides.operationTracer ??\n\t\t\tcreateOperationTracer({\n\t\t\t\tclock,\n\t\t\t\tlogger,\n\t\t\t\ttraceSink,\n\t\t\t}),\n\t\tpersistentStore: overrides.persistentStore,\n\t\tsessionStore: overrides.sessionStore,\n\t};\n}\n","// Scheduling helpers — foundation-owned convenience over raw Scheduler.\n//\n// These helpers sit above the injectable Scheduler / Clock and provide\n// reusable, cancelable wrappers for common scheduling patterns.\n\nimport type { ReadableSignalTrait } from \"../signals/types\";\nimport type { CancelableHandle, Clock, Scheduler } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Shared types\n// ---------------------------------------------------------------------------\n\n/** Subscription handle returned by input-source adapters. */\nexport interface Subscription {\n\t/** Unsubscribe and release resources. */\n\tunsubscribe(): void;\n}\n\nexport interface FromSignalOptions<T> {\n\t/** Signal to observe. */\n\tsignal: ReadableSignalTrait<T>;\n\t/** Callback invoked when the signal value changes. */\n\tcallback: (value: T) => void;\n\t/**\n\t * Emit the current snapshot immediately after subscription.\n\t * Defaults to `false`.\n\t */\n\temitInitialValue?: boolean;\n}\n\nexport const PromiseSettlementKind = {\n\tFulfilled: \"fulfilled\",\n\tRejected: \"rejected\",\n} as const;\n\nexport type PromiseSettlementKind =\n\t(typeof PromiseSettlementKind)[keyof typeof PromiseSettlementKind];\n\nexport type PromiseSettlement<T> =\n\t| {\n\t\t\tkind: typeof PromiseSettlementKind.Fulfilled;\n\t\t\tvalue: T;\n\t }\n\t| {\n\t\t\tkind: typeof PromiseSettlementKind.Rejected;\n\t\t\treason: unknown;\n\t };\n\nexport interface FromPromiseOptions<T> {\n\t/** Promise-like source to observe. */\n\tpromise: PromiseLike<T>;\n\t/** Callback invoked when the promise settles. */\n\tcallback: (settlement: PromiseSettlement<T>) => void;\n}\n\n// ---------------------------------------------------------------------------\n// timer\n// ---------------------------------------------------------------------------\n\n/** Options for {@link timer}. */\nexport interface TimerOptions {\n\t/** Scheduler to use (platform default if omitted). */\n\tscheduler: Scheduler;\n\t/** Delay in milliseconds. */\n\tdelayMs: number;\n\t/** Callback to invoke after the delay. */\n\tcallback: () => void;\n}\n\n/**\n * Schedule a one-shot callback after a delay.\n *\n * Returns a {@link CancelableHandle} that can cancel the pending timer.\n *\n * @example\n * ```ts\n * const handle = timer({\n * scheduler: runtime.scheduler,\n * delayMs: 5000,\n * callback: () => console.log(\"fired\"),\n * });\n * // Cancel before it fires:\n * handle.cancel();\n * ```\n */\nexport function timer(options: TimerOptions): CancelableHandle {\n\treturn options.scheduler.setTimeout(options.delayMs, options.callback);\n}\n\n// ---------------------------------------------------------------------------\n// interval\n// ---------------------------------------------------------------------------\n\n/** Options for {@link interval}. */\nexport interface IntervalOptions {\n\t/** Scheduler to use. */\n\tscheduler: Scheduler;\n\t/** Interval period in milliseconds. */\n\tperiodMs: number;\n\t/** Callback to invoke on each tick. */\n\tcallback: () => void;\n}\n\n/**\n * Schedule a repeating callback at a fixed interval.\n *\n * Built on top of `Scheduler.setTimeout` so it works with deterministic\n * test schedulers. Returns a {@link CancelableHandle} to stop the interval.\n *\n * @example\n * ```ts\n * const handle = interval({\n * scheduler: runtime.scheduler,\n * periodMs: 30_000,\n * callback: () => refreshTokens(),\n * });\n * // Stop:\n * handle.cancel();\n * ```\n */\nexport function interval(options: IntervalOptions): CancelableHandle {\n\tlet canceled = false;\n\tlet currentHandle: CancelableHandle | null = null;\n\n\tfunction tick(): void {\n\t\tif (canceled) return;\n\t\toptions.callback();\n\t\tscheduleNext();\n\t}\n\n\tfunction scheduleNext(): void {\n\t\tif (canceled) return;\n\t\tcurrentHandle = options.scheduler.setTimeout(options.periodMs, tick);\n\t}\n\n\t// Start the first tick.\n\tscheduleNext();\n\n\treturn {\n\t\tcancel() {\n\t\t\tcanceled = true;\n\t\t\tcurrentHandle?.cancel();\n\t\t\tcurrentHandle = null;\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// scheduleAt\n// ---------------------------------------------------------------------------\n\n/** Options for {@link scheduleAt}. */\nexport interface ScheduleAtOptions {\n\t/** Scheduler to use. */\n\tscheduler: Scheduler;\n\t/** Clock to use for computing the delay. */\n\tclock: Clock;\n\t/** Target epoch milliseconds at which the callback should fire. */\n\tatMs: number;\n\t/** Callback to invoke at (or after) the target time. */\n\tcallback: () => void;\n}\n\n/**\n * Schedule a callback at a specific wall-clock time.\n *\n * Computes the delay from `clock.now()` to `atMs` and delegates to\n * `Scheduler.setTimeout`. If the target time is already in the past,\n * the callback fires on the next scheduler tick (delay 0).\n *\n * @example\n * ```ts\n * const handle = scheduleAt({\n * scheduler: runtime.scheduler,\n * clock: runtime.clock,\n * atMs: tokenExpiresAtMs - 30_000,\n * callback: () => refreshToken(),\n * });\n * ```\n */\nexport function scheduleAt(options: ScheduleAtOptions): CancelableHandle {\n\tconst delay = Math.max(0, options.atMs - options.clock.now());\n\treturn options.scheduler.setTimeout(delay, options.callback);\n}\n\n// ---------------------------------------------------------------------------\n// fromSignal\n// ---------------------------------------------------------------------------\n\n/**\n * Adapt an SDK signal into the shared {@link Subscription} callback model.\n *\n * @example\n * ```ts\n * const sub = fromSignal({\n * signal: authState,\n * callback: (snapshot) => console.log(snapshot),\n * });\n * sub.unsubscribe();\n * ```\n */\nexport function fromSignal<T>(options: FromSignalOptions<T>): Subscription {\n\tif (options.emitInitialValue) {\n\t\toptions.callback(options.signal.get());\n\t}\n\n\tconst unsubscribe = options.signal.subscribe(() => {\n\t\toptions.callback(options.signal.get());\n\t});\n\n\treturn {\n\t\tunsubscribe() {\n\t\t\tunsubscribe();\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// fromPromise\n// ---------------------------------------------------------------------------\n\n/**\n * Adapt a promise settlement into the shared {@link Subscription} callback model.\n *\n * This helper is intentionally thin: it reports one settlement and lets the\n * consumer decide how to model pending/fulfilled/error state.\n *\n * @example\n * ```ts\n * const sub = fromPromise({\n * promise: fetchConfig(),\n * callback: (settlement) => {\n * if (settlement.kind === PromiseSettlementKind.Fulfilled) {\n * console.log(settlement.value);\n * }\n * },\n * });\n * sub.unsubscribe();\n * ```\n */\nexport function fromPromise<T>(options: FromPromiseOptions<T>): Subscription {\n\tlet active = true;\n\n\tvoid Promise.resolve(options.promise).then(\n\t\t(value) => {\n\t\t\tif (!active) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toptions.callback({\n\t\t\t\tkind: PromiseSettlementKind.Fulfilled,\n\t\t\t\tvalue,\n\t\t\t});\n\t\t},\n\t\t(reason) => {\n\t\t\tif (!active) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toptions.callback({\n\t\t\t\tkind: PromiseSettlementKind.Rejected,\n\t\t\t\treason,\n\t\t\t});\n\t\t},\n\t);\n\n\treturn {\n\t\tunsubscribe() {\n\t\t\tactive = false;\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// fromEventPattern\n// ---------------------------------------------------------------------------\n\n/** Options for {@link fromEventPattern}. */\nexport interface FromEventPatternOptions<T> {\n\t/**\n\t * Called to install the event listener. Should return whatever handle\n\t * is needed by `removeHandler` to unsubscribe.\n\t */\n\taddHandler: (handler: (value: T) => void) => void;\n\t/**\n\t * Called to uninstall the event listener.\n\t */\n\tremoveHandler: (handler: (value: T) => void) => void;\n\t/** Callback invoked each time the event fires. */\n\tcallback: (value: T) => void;\n}\n\n/**\n * Adapt an arbitrary add/remove event pattern into a {@link Subscription}.\n *\n * This is a thin bridge between imperative event APIs (e.g. `addEventListener`\n * / `removeEventListener`) and the SDK's subscription model.\n *\n * @example\n * ```ts\n * const sub = fromEventPattern<Event>({\n * addHandler: (h) => document.addEventListener(\"visibilitychange\", h),\n * removeHandler: (h) => document.removeEventListener(\"visibilitychange\", h),\n * callback: () => onVisibilityChange(),\n * });\n * // Cleanup:\n * sub.unsubscribe();\n * ```\n */\nexport function fromEventPattern<T>(\n\toptions: FromEventPatternOptions<T>,\n): Subscription {\n\tconst handler = (value: T): void => {\n\t\toptions.callback(value);\n\t};\n\toptions.addHandler(handler);\n\treturn {\n\t\tunsubscribe() {\n\t\t\toptions.removeHandler(handler);\n\t\t},\n\t};\n}\n","import { fromEventPattern, type Subscription } from \"../scheduling/helpers\";\n\nexport interface AbortSignalSource {\n\taborted: boolean;\n\treason: unknown;\n\taddEventListener(type: string, listener: EventListener): void;\n\tremoveEventListener(type: string, listener: EventListener): void;\n}\n\nexport interface FromAbortSignalOptions {\n\t/** AbortSignal to observe. */\n\tsignal?: AbortSignalSource;\n\t/** Callback invoked when the signal aborts. */\n\tcallback: (reason: unknown) => void;\n\t/**\n\t * Emit immediately when the signal is already aborted at subscribe time.\n\t * Defaults to `false`.\n\t */\n\temitIfAborted?: boolean;\n}\n\nexport interface StorageEventTarget {\n\taddEventListener(type: string, listener: EventListener): void;\n\tremoveEventListener(type: string, listener: EventListener): void;\n}\n\nexport interface FromStorageEventOptions {\n\t/**\n\t * Storage-event target. Defaults to `globalThis`, which is appropriate for\n\t * browser hosts and jsdom-based tests.\n\t */\n\ttarget?: StorageEventTarget;\n\t/** Callback invoked for each browser `storage` event. */\n\tcallback: (event: StorageEvent) => void;\n}\n\n/**\n * Adapt a browser AbortSignal into the shared Subscription model.\n */\nexport function fromAbortSignal(options: FromAbortSignalOptions): Subscription {\n\tconst signal = options.signal;\n\tif (!signal) {\n\t\treturn {\n\t\t\tunsubscribe() {},\n\t\t};\n\t}\n\n\tif (options.emitIfAborted && signal.aborted) {\n\t\toptions.callback(signal.reason);\n\t}\n\n\treturn fromEventPattern<Event>({\n\t\taddHandler: (handler) => {\n\t\t\tsignal.addEventListener(\"abort\", handler);\n\t\t},\n\t\tremoveHandler: (handler) => {\n\t\t\tsignal.removeEventListener(\"abort\", handler);\n\t\t},\n\t\tcallback: () => {\n\t\t\toptions.callback(signal.reason);\n\t\t},\n\t});\n}\n\n/**\n * Adapt browser `storage` events into the shared Subscription model.\n */\nexport function fromStorageEvent(\n\toptions: FromStorageEventOptions,\n): Subscription {\n\tconst target = options.target ?? (globalThis as StorageEventTarget);\n\n\treturn fromEventPattern<Event>({\n\t\taddHandler: (handler) => {\n\t\t\ttarget.addEventListener(\"storage\", handler);\n\t\t},\n\t\tremoveHandler: (handler) => {\n\t\t\ttarget.removeEventListener(\"storage\", handler);\n\t\t},\n\t\tcallback: (event) => {\n\t\t\toptions.callback(event as StorageEvent);\n\t\t},\n\t});\n}\n","import type {\n\tCancellationTokenTrait,\n\tDisposableTrait,\n} from \"../cancellation/types\";\nimport { ClientError } from \"../errors/client-error\";\nimport { ClientErrorKind, ClientErrorSource } from \"../errors/types\";\nimport { fromAbortSignal } from \"./input-sources\";\n\nexport interface AbortSignalBridge {\n\tsignal?: AbortSignal;\n\tdispose(): void;\n}\n\n/**\n * Bridge a web `AbortSignal` back into the foundation cancellation contract.\n *\n * This is the canonical consumer-side path for browser hosts that receive an\n * `AbortSignal` from framework/runtime APIs (for example React Query queryFns)\n * but need to call SDK surfaces that accept `CancellationTokenTrait`.\n */\nexport function createCancellationTokenFromAbortSignal(\n\tsignal?: AbortSignal,\n): CancellationTokenTrait | undefined {\n\tif (!signal) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tget isCancellationRequested() {\n\t\t\treturn signal.aborted;\n\t\t},\n\t\tget reason() {\n\t\t\treturn signal.reason;\n\t\t},\n\t\tonCancellationRequested(listener: (reason: unknown) => void) {\n\t\t\tconst subscription = fromAbortSignal({\n\t\t\t\tsignal,\n\t\t\t\tcallback: listener,\n\t\t\t\temitIfAborted: true,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tdispose() {\n\t\t\t\t\tsubscription.unsubscribe();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tthrowIfCancellationRequested() {\n\t\t\tif (signal.aborted) {\n\t\t\t\tthrow new ClientError({\n\t\t\t\t\tkind: ClientErrorKind.Cancelled,\n\t\t\t\t\tmessage: \"Request was cancelled via AbortSignal\",\n\t\t\t\t\tcode: \"client.cancelled\",\n\t\t\t\t\tsource: ClientErrorSource.Transport,\n\t\t\t\t\tcause: signal.reason,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t};\n}\n\n/**\n * Bridge foundation cancellation to web `AbortSignal` without exposing\n * `AbortSignal` in core contracts.\n */\nexport function createAbortSignalBridge(\n\ttoken?: CancellationTokenTrait,\n): AbortSignalBridge {\n\tif (!token) {\n\t\treturn {\n\t\t\tsignal: undefined,\n\t\t\tdispose() {},\n\t\t};\n\t}\n\n\tconst controller = new AbortController();\n\tlet subscription: DisposableTrait | null = token.onCancellationRequested(\n\t\t(reason) => {\n\t\t\tcontroller.abort(reason);\n\t\t},\n\t);\n\n\tif (token.isCancellationRequested) {\n\t\tcontroller.abort(token.reason);\n\t}\n\n\treturn {\n\t\tsignal: controller.signal,\n\t\tdispose() {\n\t\t\tsubscription?.dispose();\n\t\t\tsubscription = null;\n\t\t},\n\t};\n}\n\nexport function normalizeAbortError(\n\ttoken: CancellationTokenTrait | undefined,\n\terror: unknown,\n): unknown {\n\tif (!isAbortError(error) && !token?.isCancellationRequested) {\n\t\treturn error;\n\t}\n\n\tconst reason = token?.reason;\n\tif (reason instanceof ClientError) {\n\t\treturn reason;\n\t}\n\n\tif (reason instanceof Error) {\n\t\treturn new ClientError({\n\t\t\tkind: ClientErrorKind.Cancelled,\n\t\t\tmessage: reason.message,\n\t\t\tcode: \"client.cancelled\",\n\t\t\tsource: ClientErrorSource.Transport,\n\t\t\tcause: reason,\n\t\t});\n\t}\n\n\treturn new ClientError({\n\t\tkind: ClientErrorKind.Cancelled,\n\t\tmessage: \"HTTP request was cancelled\",\n\t\tcode: \"client.cancelled\",\n\t\tsource: ClientErrorSource.Transport,\n\t\tcause: reason ?? error,\n\t});\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"name\" in error &&\n\t\terror.name === \"AbortError\"\n\t);\n}\n","import {\n\tcreateAbortSignalBridge,\n\tnormalizeAbortError,\n} from \"../web/cancellation\";\nimport type { HttpRequest, HttpResponse, HttpTransport } from \"./types\";\n\nexport const FetchTransportRedirectKind = {\n\tFollow: \"follow\",\n\tManual: \"manual\",\n} as const;\n\nexport type FetchTransportRedirectKind =\n\t(typeof FetchTransportRedirectKind)[keyof typeof FetchTransportRedirectKind];\n\nexport interface FetchTransportOptions {\n\t/**\n\t * How to handle HTTP redirects.\n\t * - `\"follow\"`: automatically follow redirects (default fetch behavior)\n\t * - `\"manual\"`: capture redirect responses as-is (needed for fragment-based protocols)\n\t */\n\tredirect?: FetchTransportRedirectKind;\n}\n\n/**\n * Default `HttpTransport` backed by the global `fetch` API.\n *\n * The caller is responsible for ensuring `fetch` is available in the runtime.\n * No polyfill is injected — see the polyfill strategy in the design guide.\n */\nexport function createFetchTransport(\n\toptions: FetchTransportOptions = {},\n): HttpTransport {\n\tconst redirect = options.redirect ?? FetchTransportRedirectKind.Manual;\n\n\treturn {\n\t\tasync execute(request: HttpRequest): Promise<HttpResponse> {\n\t\t\tconst abortBridge = createAbortSignalBridge(request.cancellationToken);\n\t\t\tconst init: RequestInit = {\n\t\t\t\tmethod: request.method,\n\t\t\t\theaders: request.headers,\n\t\t\t\tredirect,\n\t\t\t\tsignal: abortBridge.signal,\n\t\t\t};\n\n\t\t\tif (\n\t\t\t\trequest.body !== undefined &&\n\t\t\t\trequest.method !== \"GET\" &&\n\t\t\t\trequest.method !== \"HEAD\"\n\t\t\t) {\n\t\t\t\tinit.body =\n\t\t\t\t\ttypeof request.body === \"string\"\n\t\t\t\t\t\t? request.body\n\t\t\t\t\t\t: JSON.stringify(request.body);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(request.url, init);\n\n\t\t\t\tconst responseHeaders: Record<string, string> = {};\n\t\t\t\tres.headers.forEach((value, key) => {\n\t\t\t\t\tresponseHeaders[key] = value;\n\t\t\t\t});\n\n\t\t\t\tlet body: unknown;\n\t\t\t\tconst contentType = res.headers.get(\"content-type\");\n\t\t\t\tif (contentType?.includes(\"application/json\")) {\n\t\t\t\t\tbody = await res.json();\n\t\t\t\t} else if (\n\t\t\t\t\tres.status !== 302 &&\n\t\t\t\t\tres.status !== 303 &&\n\t\t\t\t\tres.status !== 301\n\t\t\t\t) {\n\t\t\t\t\tbody = await res.text();\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tstatus: res.status,\n\t\t\t\t\theaders: responseHeaders,\n\t\t\t\t\tbody,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthrow normalizeAbortError(request.cancellationToken, error);\n\t\t\t} finally {\n\t\t\t\tabortBridge.dispose();\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { n as ReadableSignalTrait } from "./types-DQc088ZP.mjs";
|
|
2
|
-
import { Observable } from "rxjs";
|
|
3
|
-
|
|
4
|
-
//#region src/events/types.d.ts
|
|
5
|
-
/** Subscription handle with explicit unsubscribe. */
|
|
6
|
-
interface EventSubscriptionTrait {
|
|
7
|
-
unsubscribe(): void;
|
|
8
|
-
}
|
|
9
|
-
/** Observer for event streams — mirrors the Observable observer pattern. */
|
|
10
|
-
interface EventObserver<T> {
|
|
11
|
-
next?(value: T): void;
|
|
12
|
-
error?(error: unknown): void;
|
|
13
|
-
complete?(): void;
|
|
14
|
-
}
|
|
15
|
-
/** Read-only event stream — lazy push-based sequence. */
|
|
16
|
-
interface EventStreamTrait<T> {
|
|
17
|
-
subscribe(observer: EventObserver<T>): EventSubscriptionTrait;
|
|
18
|
-
}
|
|
19
|
-
/** Hot event producer. */
|
|
20
|
-
interface SubjectTrait<T> extends EventStreamTrait<T> {
|
|
21
|
-
next(value: T): void;
|
|
22
|
-
error(error: unknown): void;
|
|
23
|
-
complete(): void;
|
|
24
|
-
}
|
|
25
|
-
/** Hot event producer that replays recent values to late subscribers. */
|
|
26
|
-
interface ReplaySubjectTrait<T> extends SubjectTrait<T> {
|
|
27
|
-
readonly bufferSize: number;
|
|
28
|
-
}
|
|
29
|
-
declare const EventSourceKind: {
|
|
30
|
-
readonly User: "user";
|
|
31
|
-
readonly Timer: "timer";
|
|
32
|
-
readonly Http: "http";
|
|
33
|
-
readonly Storage: "storage";
|
|
34
|
-
readonly Framework: "framework";
|
|
35
|
-
readonly System: "system";
|
|
36
|
-
};
|
|
37
|
-
type EventSourceKind = (typeof EventSourceKind)[keyof typeof EventSourceKind];
|
|
38
|
-
type EventSource = {
|
|
39
|
-
kind: typeof EventSourceKind.User;
|
|
40
|
-
actor?: string;
|
|
41
|
-
} | {
|
|
42
|
-
kind: typeof EventSourceKind.Timer;
|
|
43
|
-
timer: string;
|
|
44
|
-
} | {
|
|
45
|
-
kind: typeof EventSourceKind.Http;
|
|
46
|
-
requestId: string;
|
|
47
|
-
endpoint?: string;
|
|
48
|
-
} | {
|
|
49
|
-
kind: typeof EventSourceKind.Storage;
|
|
50
|
-
operation: string;
|
|
51
|
-
} | {
|
|
52
|
-
kind: typeof EventSourceKind.Framework;
|
|
53
|
-
name: string;
|
|
54
|
-
} | {
|
|
55
|
-
kind: typeof EventSourceKind.System;
|
|
56
|
-
subsystem: string;
|
|
57
|
-
};
|
|
58
|
-
interface RuntimeEventEnvelope<TType extends string, TPayload> {
|
|
59
|
-
id: string;
|
|
60
|
-
type: TType;
|
|
61
|
-
at: number;
|
|
62
|
-
source: EventSource;
|
|
63
|
-
payload: TPayload;
|
|
64
|
-
}
|
|
65
|
-
//#endregion
|
|
66
|
-
//#region src/events/event-stream.d.ts
|
|
67
|
-
/**
|
|
68
|
-
* Create a new event stream from a producer function.
|
|
69
|
-
*
|
|
70
|
-
* The producer receives an observer and should call `next()` to emit values,
|
|
71
|
-
* `error()` to signal an error, and `complete()` to signal completion.
|
|
72
|
-
* It may return a teardown function that will be called on unsubscribe.
|
|
73
|
-
*/
|
|
74
|
-
declare function createEventStream<T>(producer: (observer: EventObserver<T>) => (() => void) | void): EventStreamTrait<T>;
|
|
75
|
-
declare function createSubject<T>(): SubjectTrait<T>;
|
|
76
|
-
declare function createReplaySubject<T>(bufferSize?: number): ReplaySubjectTrait<T>;
|
|
77
|
-
declare function toRxObservable<T>(stream: EventStreamTrait<T>): Observable<T>;
|
|
78
|
-
declare function fromRxObservable<T>(observable: Observable<T>): EventStreamTrait<T>;
|
|
79
|
-
//#endregion
|
|
80
|
-
//#region src/events/operators.d.ts
|
|
81
|
-
type EventOperator<A, B> = (source: EventStreamTrait<A>) => EventStreamTrait<B>;
|
|
82
|
-
declare function pipe<A>(source: EventStreamTrait<A>): EventStreamTrait<A>;
|
|
83
|
-
declare function pipe<A, B>(source: EventStreamTrait<A>, op1: EventOperator<A, B>): EventStreamTrait<B>;
|
|
84
|
-
declare function pipe<A, B, C>(source: EventStreamTrait<A>, op1: EventOperator<A, B>, op2: EventOperator<B, C>): EventStreamTrait<C>;
|
|
85
|
-
declare function pipe<A, B, C, D>(source: EventStreamTrait<A>, op1: EventOperator<A, B>, op2: EventOperator<B, C>, op3: EventOperator<C, D>): EventStreamTrait<D>;
|
|
86
|
-
declare function map<A, B>(fn: (value: A) => B): EventOperator<A, B>;
|
|
87
|
-
declare function filter<A>(predicate: (value: A) => boolean): EventOperator<A, A>;
|
|
88
|
-
declare function tap<A>(fn: (value: A) => void): EventOperator<A, A>;
|
|
89
|
-
declare function takeUntil<A>(notifier: EventStreamTrait<unknown>): EventOperator<A, A>;
|
|
90
|
-
declare function finalize<A>(fn: () => void): EventOperator<A, A>;
|
|
91
|
-
declare function merge$1<A>(...sources: EventStreamTrait<A>[]): EventStreamTrait<A>;
|
|
92
|
-
declare function share<A>(): EventOperator<A, A>;
|
|
93
|
-
declare function shareReplay<A>(bufferSize?: number): EventOperator<A, A>;
|
|
94
|
-
declare function switchMap<A, B>(fn: (value: A) => EventStreamTrait<B>): EventOperator<A, B>;
|
|
95
|
-
declare function concatMap<A, B>(fn: (value: A) => EventStreamTrait<B>): EventOperator<A, B>;
|
|
96
|
-
declare function exhaustMap<A, B>(fn: (value: A) => EventStreamTrait<B>): EventOperator<A, B>;
|
|
97
|
-
declare function debounceTime<A>(durationMs: number): EventOperator<A, A>;
|
|
98
|
-
declare function throttleTime<A>(durationMs: number): EventOperator<A, A>;
|
|
99
|
-
declare function withLatestFromSignal<A, B>(signal: ReadableSignalTrait<B>): EventOperator<A, [A, B]>;
|
|
100
|
-
//#endregion
|
|
101
|
-
export { EventSource as C, ReplaySubjectTrait as D, EventSubscriptionTrait as E, RuntimeEventEnvelope as O, EventObserver as S, EventStreamTrait as T, createEventStream as _, filter as a, fromRxObservable as b, merge$1 as c, shareReplay as d, switchMap as f, withLatestFromSignal as g, throttleTime as h, exhaustMap as i, SubjectTrait as k, pipe as l, tap as m, concatMap as n, finalize as o, takeUntil as p, debounceTime as r, map as s, EventOperator as t, share as u, createReplaySubject as v, EventSourceKind as w, toRxObservable as x, createSubject as y };
|
|
102
|
-
//# sourceMappingURL=index-C_wgl6dW.d.mts.map
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { a as RecordStore, n as EphemeralFlowStore, r as KeyedEphemeralFlowStore, t as Codec } from "./types-C59fcM5W.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/persistence/ephemeral-flow-store.d.ts
|
|
4
|
-
interface CreateEphemeralFlowStoreOptions<T> {
|
|
5
|
-
store: RecordStore;
|
|
6
|
-
key: string;
|
|
7
|
-
codec?: Codec<T>;
|
|
8
|
-
}
|
|
9
|
-
interface CreateKeyedEphemeralFlowStoreOptions<T> {
|
|
10
|
-
store: RecordStore;
|
|
11
|
-
keyPrefix: string;
|
|
12
|
-
codec?: Codec<T>;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Create a typed ephemeral flow-state store backed by a low-level `RecordStore`.
|
|
16
|
-
*
|
|
17
|
-
* Intended for short-lived browser/session coordination state such as pending
|
|
18
|
-
* redirects or callback fragments.
|
|
19
|
-
*/
|
|
20
|
-
declare function createEphemeralFlowStore<T>(options: CreateEphemeralFlowStoreOptions<T>): EphemeralFlowStore<T>;
|
|
21
|
-
/**
|
|
22
|
-
* Create a typed keyed ephemeral flow-state store backed by a low-level
|
|
23
|
-
* `RecordStore`.
|
|
24
|
-
*
|
|
25
|
-
* Intended for short-lived browser/session coordination state where multiple
|
|
26
|
-
* pending records must coexist and be consumed independently.
|
|
27
|
-
*/
|
|
28
|
-
declare function createKeyedEphemeralFlowStore<T>(options: CreateKeyedEphemeralFlowStoreOptions<T>): KeyedEphemeralFlowStore<T>;
|
|
29
|
-
//#endregion
|
|
30
|
-
//#region src/persistence/json-codec.d.ts
|
|
31
|
-
/** Default JSON codec. */
|
|
32
|
-
declare function createJsonCodec<T>(): Codec<T>;
|
|
33
|
-
//#endregion
|
|
34
|
-
//#region src/persistence/memory-store.d.ts
|
|
35
|
-
/** In-memory `RecordStore` — useful for tests and SSR. */
|
|
36
|
-
declare function createInMemoryRecordStore(): RecordStore;
|
|
37
|
-
//#endregion
|
|
38
|
-
export { createEphemeralFlowStore as a, CreateKeyedEphemeralFlowStoreOptions as i, createJsonCodec as n, createKeyedEphemeralFlowStore as o, CreateEphemeralFlowStoreOptions as r, createInMemoryRecordStore as t };
|
|
39
|
-
//# sourceMappingURL=index-DbYSFHDe.d.mts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { a as RecordStore, i as PersistentAuthStore, n as EphemeralFlowStore, o as RecoverableStateStore, r as KeyedEphemeralFlowStore, s as StoredEnvelope, t as Codec } from "../types-C59fcM5W.mjs";
|
|
2
|
-
import { a as createEphemeralFlowStore, i as CreateKeyedEphemeralFlowStoreOptions, n as createJsonCodec, o as createKeyedEphemeralFlowStore, r as CreateEphemeralFlowStoreOptions, t as createInMemoryRecordStore } from "../index-DbYSFHDe.mjs";
|
|
3
|
-
export { Codec, CreateEphemeralFlowStoreOptions, CreateKeyedEphemeralFlowStoreOptions, EphemeralFlowStore, KeyedEphemeralFlowStore, PersistentAuthStore, RecordStore, RecoverableStateStore, StoredEnvelope, createEphemeralFlowStore, createInMemoryRecordStore, createJsonCodec, createKeyedEphemeralFlowStore };
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { i as createJsonCodec, n as createEphemeralFlowStore, r as createKeyedEphemeralFlowStore, t as createInMemoryRecordStore } from "../persistence-CSB8770k.mjs";
|
|
2
|
-
export { createEphemeralFlowStore, createInMemoryRecordStore, createJsonCodec, createKeyedEphemeralFlowStore };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { a as RecordStore } from "../../types-C59fcM5W.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/persistence/web/stores.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* `RecordStore` backed by `localStorage`.
|
|
6
|
-
* @param prefix Optional key prefix to isolate the keyspace.
|
|
7
|
-
*/
|
|
8
|
-
declare function createLocalStorageStore(prefix?: string): RecordStore;
|
|
9
|
-
/**
|
|
10
|
-
* `RecordStore` backed by `sessionStorage`.
|
|
11
|
-
* @param prefix Optional key prefix to isolate the keyspace.
|
|
12
|
-
*/
|
|
13
|
-
declare function createSessionStorageStore(prefix?: string): RecordStore;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { createLocalStorageStore, createSessionStorageStore };
|
|
16
|
-
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
//#region src/persistence/web/stores.ts
|
|
2
|
-
/**
|
|
3
|
-
* `RecordStore` backed by `localStorage`.
|
|
4
|
-
* @param prefix Optional key prefix to isolate the keyspace.
|
|
5
|
-
*/
|
|
6
|
-
function createLocalStorageStore(prefix = "") {
|
|
7
|
-
return {
|
|
8
|
-
async get(key) {
|
|
9
|
-
return globalThis.localStorage.getItem(prefix + key);
|
|
10
|
-
},
|
|
11
|
-
async set(key, value) {
|
|
12
|
-
globalThis.localStorage.setItem(prefix + key, value);
|
|
13
|
-
},
|
|
14
|
-
async take(key) {
|
|
15
|
-
const storageKey = prefix + key;
|
|
16
|
-
const value = globalThis.localStorage.getItem(storageKey);
|
|
17
|
-
if (value !== null) globalThis.localStorage.removeItem(storageKey);
|
|
18
|
-
return value;
|
|
19
|
-
},
|
|
20
|
-
async remove(key) {
|
|
21
|
-
globalThis.localStorage.removeItem(prefix + key);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* `RecordStore` backed by `sessionStorage`.
|
|
27
|
-
* @param prefix Optional key prefix to isolate the keyspace.
|
|
28
|
-
*/
|
|
29
|
-
function createSessionStorageStore(prefix = "") {
|
|
30
|
-
return {
|
|
31
|
-
async get(key) {
|
|
32
|
-
return globalThis.sessionStorage.getItem(prefix + key);
|
|
33
|
-
},
|
|
34
|
-
async set(key, value) {
|
|
35
|
-
globalThis.sessionStorage.setItem(prefix + key, value);
|
|
36
|
-
},
|
|
37
|
-
async take(key) {
|
|
38
|
-
const storageKey = prefix + key;
|
|
39
|
-
const value = globalThis.sessionStorage.getItem(storageKey);
|
|
40
|
-
if (value !== null) globalThis.sessionStorage.removeItem(storageKey);
|
|
41
|
-
return value;
|
|
42
|
-
},
|
|
43
|
-
async remove(key) {
|
|
44
|
-
globalThis.sessionStorage.removeItem(prefix + key);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
//#endregion
|
|
49
|
-
export { createLocalStorageStore, createSessionStorageStore };
|
|
50
|
-
|
|
51
|
-
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/persistence/web/stores.ts"],"sourcesContent":["import type { RecordStore } from \"../types\";\n\n/**\n * `RecordStore` backed by `localStorage`.\n * @param prefix Optional key prefix to isolate the keyspace.\n */\nexport function createLocalStorageStore(prefix = \"\"): RecordStore {\n\treturn {\n\t\tasync get(key: string): Promise<string | null> {\n\t\t\treturn globalThis.localStorage.getItem(prefix + key);\n\t\t},\n\t\tasync set(key: string, value: string): Promise<void> {\n\t\t\tglobalThis.localStorage.setItem(prefix + key, value);\n\t\t},\n\t\tasync take(key: string): Promise<string | null> {\n\t\t\tconst storageKey = prefix + key;\n\t\t\tconst value = globalThis.localStorage.getItem(storageKey);\n\t\t\tif (value !== null) {\n\t\t\t\tglobalThis.localStorage.removeItem(storageKey);\n\t\t\t}\n\t\t\treturn value;\n\t\t},\n\t\tasync remove(key: string): Promise<void> {\n\t\t\tglobalThis.localStorage.removeItem(prefix + key);\n\t\t},\n\t};\n}\n\n/**\n * `RecordStore` backed by `sessionStorage`.\n * @param prefix Optional key prefix to isolate the keyspace.\n */\nexport function createSessionStorageStore(prefix = \"\"): RecordStore {\n\treturn {\n\t\tasync get(key: string): Promise<string | null> {\n\t\t\treturn globalThis.sessionStorage.getItem(prefix + key);\n\t\t},\n\t\tasync set(key: string, value: string): Promise<void> {\n\t\t\tglobalThis.sessionStorage.setItem(prefix + key, value);\n\t\t},\n\t\tasync take(key: string): Promise<string | null> {\n\t\t\tconst storageKey = prefix + key;\n\t\t\tconst value = globalThis.sessionStorage.getItem(storageKey);\n\t\t\tif (value !== null) {\n\t\t\t\tglobalThis.sessionStorage.removeItem(storageKey);\n\t\t\t}\n\t\t\treturn value;\n\t\t},\n\t\tasync remove(key: string): Promise<void> {\n\t\t\tglobalThis.sessionStorage.removeItem(prefix + key);\n\t\t},\n\t};\n}\n"],"mappings":";;;;;AAMA,SAAgB,wBAAwB,SAAS,IAAiB;AACjE,QAAO;EACN,MAAM,IAAI,KAAqC;AAC9C,UAAO,WAAW,aAAa,QAAQ,SAAS,IAAI;;EAErD,MAAM,IAAI,KAAa,OAA8B;AACpD,cAAW,aAAa,QAAQ,SAAS,KAAK,MAAM;;EAErD,MAAM,KAAK,KAAqC;GAC/C,MAAM,aAAa,SAAS;GAC5B,MAAM,QAAQ,WAAW,aAAa,QAAQ,WAAW;AACzD,OAAI,UAAU,KACb,YAAW,aAAa,WAAW,WAAW;AAE/C,UAAO;;EAER,MAAM,OAAO,KAA4B;AACxC,cAAW,aAAa,WAAW,SAAS,IAAI;;EAEjD;;;;;;AAOF,SAAgB,0BAA0B,SAAS,IAAiB;AACnE,QAAO;EACN,MAAM,IAAI,KAAqC;AAC9C,UAAO,WAAW,eAAe,QAAQ,SAAS,IAAI;;EAEvD,MAAM,IAAI,KAAa,OAA8B;AACpD,cAAW,eAAe,QAAQ,SAAS,KAAK,MAAM;;EAEvD,MAAM,KAAK,KAAqC;GAC/C,MAAM,aAAa,SAAS;GAC5B,MAAM,QAAQ,WAAW,eAAe,QAAQ,WAAW;AAC3D,OAAI,UAAU,KACb,YAAW,eAAe,WAAW,WAAW;AAEjD,UAAO;;EAER,MAAM,OAAO,KAA4B;AACxC,cAAW,eAAe,WAAW,SAAS,IAAI;;EAEnD"}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
//#region src/persistence/json-codec.ts
|
|
2
|
-
/** Default JSON codec. */
|
|
3
|
-
function createJsonCodec() {
|
|
4
|
-
return {
|
|
5
|
-
encode(value) {
|
|
6
|
-
return JSON.stringify(value);
|
|
7
|
-
},
|
|
8
|
-
decode(raw) {
|
|
9
|
-
return JSON.parse(raw);
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/persistence/ephemeral-flow-store.ts
|
|
15
|
-
function resolveStorageKey(keyPrefix, key) {
|
|
16
|
-
return keyPrefix.length > 0 ? `${keyPrefix}:${key}` : key;
|
|
17
|
-
}
|
|
18
|
-
function requireRecordStoreTake(store) {
|
|
19
|
-
if (!store.take) throw new Error("Ephemeral flow stores require RecordStore.take() for atomic single-consume semantics");
|
|
20
|
-
return store.take.bind(store);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Create a typed ephemeral flow-state store backed by a low-level `RecordStore`.
|
|
24
|
-
*
|
|
25
|
-
* Intended for short-lived browser/session coordination state such as pending
|
|
26
|
-
* redirects or callback fragments.
|
|
27
|
-
*/
|
|
28
|
-
function createEphemeralFlowStore(options) {
|
|
29
|
-
const codec = options.codec ?? createJsonCodec();
|
|
30
|
-
const storeTake = requireRecordStoreTake(options.store);
|
|
31
|
-
async function load() {
|
|
32
|
-
const raw = await options.store.get(options.key);
|
|
33
|
-
return raw === null ? null : codec.decode(raw);
|
|
34
|
-
}
|
|
35
|
-
async function save(value) {
|
|
36
|
-
await options.store.set(options.key, codec.encode(value));
|
|
37
|
-
}
|
|
38
|
-
async function consume() {
|
|
39
|
-
const raw = await storeTake(options.key);
|
|
40
|
-
return raw === null ? null : codec.decode(raw);
|
|
41
|
-
}
|
|
42
|
-
async function clear() {
|
|
43
|
-
await options.store.remove(options.key);
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
load,
|
|
47
|
-
save,
|
|
48
|
-
consume,
|
|
49
|
-
clear
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Create a typed keyed ephemeral flow-state store backed by a low-level
|
|
54
|
-
* `RecordStore`.
|
|
55
|
-
*
|
|
56
|
-
* Intended for short-lived browser/session coordination state where multiple
|
|
57
|
-
* pending records must coexist and be consumed independently.
|
|
58
|
-
*/
|
|
59
|
-
function createKeyedEphemeralFlowStore(options) {
|
|
60
|
-
const codec = options.codec ?? createJsonCodec();
|
|
61
|
-
const storeTake = requireRecordStoreTake(options.store);
|
|
62
|
-
async function load(key) {
|
|
63
|
-
const raw = await options.store.get(resolveStorageKey(options.keyPrefix, key));
|
|
64
|
-
return raw === null ? null : codec.decode(raw);
|
|
65
|
-
}
|
|
66
|
-
async function save(key, value) {
|
|
67
|
-
await options.store.set(resolveStorageKey(options.keyPrefix, key), codec.encode(value));
|
|
68
|
-
}
|
|
69
|
-
async function take(key) {
|
|
70
|
-
const raw = await storeTake(resolveStorageKey(options.keyPrefix, key));
|
|
71
|
-
return raw === null ? null : codec.decode(raw);
|
|
72
|
-
}
|
|
73
|
-
async function clear(key) {
|
|
74
|
-
await options.store.remove(resolveStorageKey(options.keyPrefix, key));
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
load,
|
|
78
|
-
save,
|
|
79
|
-
take,
|
|
80
|
-
clear
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
//#endregion
|
|
84
|
-
//#region src/persistence/memory-store.ts
|
|
85
|
-
/** In-memory `RecordStore` — useful for tests and SSR. */
|
|
86
|
-
function createInMemoryRecordStore() {
|
|
87
|
-
const store = /* @__PURE__ */ new Map();
|
|
88
|
-
return {
|
|
89
|
-
async get(key) {
|
|
90
|
-
return store.get(key) ?? null;
|
|
91
|
-
},
|
|
92
|
-
async set(key, value) {
|
|
93
|
-
store.set(key, value);
|
|
94
|
-
},
|
|
95
|
-
async take(key) {
|
|
96
|
-
const value = store.get(key) ?? null;
|
|
97
|
-
if (value !== null) store.delete(key);
|
|
98
|
-
return value;
|
|
99
|
-
},
|
|
100
|
-
async remove(key) {
|
|
101
|
-
store.delete(key);
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
//#endregion
|
|
106
|
-
export { createJsonCodec as i, createEphemeralFlowStore as n, createKeyedEphemeralFlowStore as r, createInMemoryRecordStore as t };
|
|
107
|
-
|
|
108
|
-
//# sourceMappingURL=persistence-CSB8770k.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"persistence-CSB8770k.mjs","names":[],"sources":["../src/persistence/json-codec.ts","../src/persistence/ephemeral-flow-store.ts","../src/persistence/memory-store.ts"],"sourcesContent":["import type { Codec } from \"./types\";\n\n/** Default JSON codec. */\nexport function createJsonCodec<T>(): Codec<T> {\n\treturn {\n\t\tencode(value: T): string {\n\t\t\treturn JSON.stringify(value);\n\t\t},\n\t\tdecode(raw: string): T {\n\t\t\treturn JSON.parse(raw) as T;\n\t\t},\n\t};\n}\n","import { createJsonCodec } from \"./json-codec\";\nimport type {\n\tCodec,\n\tEphemeralFlowStore,\n\tKeyedEphemeralFlowStore,\n\tRecordStore,\n} from \"./types\";\n\nexport interface CreateEphemeralFlowStoreOptions<T> {\n\tstore: RecordStore;\n\tkey: string;\n\tcodec?: Codec<T>;\n}\n\nexport interface CreateKeyedEphemeralFlowStoreOptions<T> {\n\tstore: RecordStore;\n\tkeyPrefix: string;\n\tcodec?: Codec<T>;\n}\n\nfunction resolveStorageKey(keyPrefix: string, key: string): string {\n\treturn keyPrefix.length > 0 ? `${keyPrefix}:${key}` : key;\n}\n\nfunction requireRecordStoreTake(\n\tstore: RecordStore,\n): NonNullable<RecordStore[\"take\"]> {\n\tif (!store.take) {\n\t\tthrow new Error(\n\t\t\t\"Ephemeral flow stores require RecordStore.take() for atomic single-consume semantics\",\n\t\t);\n\t}\n\n\treturn store.take.bind(store);\n}\n\n/**\n * Create a typed ephemeral flow-state store backed by a low-level `RecordStore`.\n *\n * Intended for short-lived browser/session coordination state such as pending\n * redirects or callback fragments.\n */\nexport function createEphemeralFlowStore<T>(\n\toptions: CreateEphemeralFlowStoreOptions<T>,\n): EphemeralFlowStore<T> {\n\tconst codec = options.codec ?? createJsonCodec<T>();\n\tconst storeTake = requireRecordStoreTake(options.store);\n\n\tasync function load(): Promise<T | null> {\n\t\tconst raw = await options.store.get(options.key);\n\t\treturn raw === null ? null : codec.decode(raw);\n\t}\n\n\tasync function save(value: T): Promise<void> {\n\t\tawait options.store.set(options.key, codec.encode(value));\n\t}\n\n\tasync function consume(): Promise<T | null> {\n\t\tconst raw = await storeTake(options.key);\n\t\treturn raw === null ? null : codec.decode(raw);\n\t}\n\n\tasync function clear(): Promise<void> {\n\t\tawait options.store.remove(options.key);\n\t}\n\n\treturn {\n\t\tload,\n\t\tsave,\n\t\tconsume,\n\t\tclear,\n\t};\n}\n\n/**\n * Create a typed keyed ephemeral flow-state store backed by a low-level\n * `RecordStore`.\n *\n * Intended for short-lived browser/session coordination state where multiple\n * pending records must coexist and be consumed independently.\n */\nexport function createKeyedEphemeralFlowStore<T>(\n\toptions: CreateKeyedEphemeralFlowStoreOptions<T>,\n): KeyedEphemeralFlowStore<T> {\n\tconst codec = options.codec ?? createJsonCodec<T>();\n\tconst storeTake = requireRecordStoreTake(options.store);\n\n\tasync function load(key: string): Promise<T | null> {\n\t\tconst raw = await options.store.get(\n\t\t\tresolveStorageKey(options.keyPrefix, key),\n\t\t);\n\t\treturn raw === null ? null : codec.decode(raw);\n\t}\n\n\tasync function save(key: string, value: T): Promise<void> {\n\t\tawait options.store.set(\n\t\t\tresolveStorageKey(options.keyPrefix, key),\n\t\t\tcodec.encode(value),\n\t\t);\n\t}\n\n\tasync function take(key: string): Promise<T | null> {\n\t\tconst raw = await storeTake(resolveStorageKey(options.keyPrefix, key));\n\t\treturn raw === null ? null : codec.decode(raw);\n\t}\n\n\tasync function clear(key: string): Promise<void> {\n\t\tawait options.store.remove(resolveStorageKey(options.keyPrefix, key));\n\t}\n\n\treturn {\n\t\tload,\n\t\tsave,\n\t\ttake,\n\t\tclear,\n\t};\n}\n","import type { RecordStore } from \"./types\";\n\n/** In-memory `RecordStore` — useful for tests and SSR. */\nexport function createInMemoryRecordStore(): RecordStore {\n\tconst store = new Map<string, string>();\n\n\treturn {\n\t\tasync get(key: string): Promise<string | null> {\n\t\t\treturn store.get(key) ?? null;\n\t\t},\n\t\tasync set(key: string, value: string): Promise<void> {\n\t\t\tstore.set(key, value);\n\t\t},\n\t\tasync take(key: string): Promise<string | null> {\n\t\t\tconst value = store.get(key) ?? null;\n\t\t\tif (value !== null) {\n\t\t\t\tstore.delete(key);\n\t\t\t}\n\t\t\treturn value;\n\t\t},\n\t\tasync remove(key: string): Promise<void> {\n\t\t\tstore.delete(key);\n\t\t},\n\t};\n}\n"],"mappings":";;AAGA,SAAgB,kBAA+B;AAC9C,QAAO;EACN,OAAO,OAAkB;AACxB,UAAO,KAAK,UAAU,MAAM;;EAE7B,OAAO,KAAgB;AACtB,UAAO,KAAK,MAAM,IAAI;;EAEvB;;;;ACSF,SAAS,kBAAkB,WAAmB,KAAqB;AAClE,QAAO,UAAU,SAAS,IAAI,GAAG,UAAU,GAAG,QAAQ;;AAGvD,SAAS,uBACR,OACmC;AACnC,KAAI,CAAC,MAAM,KACV,OAAM,IAAI,MACT,uFACA;AAGF,QAAO,MAAM,KAAK,KAAK,MAAM;;;;;;;;AAS9B,SAAgB,yBACf,SACwB;CACxB,MAAM,QAAQ,QAAQ,SAAS,iBAAoB;CACnD,MAAM,YAAY,uBAAuB,QAAQ,MAAM;CAEvD,eAAe,OAA0B;EACxC,MAAM,MAAM,MAAM,QAAQ,MAAM,IAAI,QAAQ,IAAI;AAChD,SAAO,QAAQ,OAAO,OAAO,MAAM,OAAO,IAAI;;CAG/C,eAAe,KAAK,OAAyB;AAC5C,QAAM,QAAQ,MAAM,IAAI,QAAQ,KAAK,MAAM,OAAO,MAAM,CAAC;;CAG1D,eAAe,UAA6B;EAC3C,MAAM,MAAM,MAAM,UAAU,QAAQ,IAAI;AACxC,SAAO,QAAQ,OAAO,OAAO,MAAM,OAAO,IAAI;;CAG/C,eAAe,QAAuB;AACrC,QAAM,QAAQ,MAAM,OAAO,QAAQ,IAAI;;AAGxC,QAAO;EACN;EACA;EACA;EACA;EACA;;;;;;;;;AAUF,SAAgB,8BACf,SAC6B;CAC7B,MAAM,QAAQ,QAAQ,SAAS,iBAAoB;CACnD,MAAM,YAAY,uBAAuB,QAAQ,MAAM;CAEvD,eAAe,KAAK,KAAgC;EACnD,MAAM,MAAM,MAAM,QAAQ,MAAM,IAC/B,kBAAkB,QAAQ,WAAW,IAAI,CACzC;AACD,SAAO,QAAQ,OAAO,OAAO,MAAM,OAAO,IAAI;;CAG/C,eAAe,KAAK,KAAa,OAAyB;AACzD,QAAM,QAAQ,MAAM,IACnB,kBAAkB,QAAQ,WAAW,IAAI,EACzC,MAAM,OAAO,MAAM,CACnB;;CAGF,eAAe,KAAK,KAAgC;EACnD,MAAM,MAAM,MAAM,UAAU,kBAAkB,QAAQ,WAAW,IAAI,CAAC;AACtE,SAAO,QAAQ,OAAO,OAAO,MAAM,OAAO,IAAI;;CAG/C,eAAe,MAAM,KAA4B;AAChD,QAAM,QAAQ,MAAM,OAAO,kBAAkB,QAAQ,WAAW,IAAI,CAAC;;AAGtE,QAAO;EACN;EACA;EACA;EACA;EACA;;;;;AChHF,SAAgB,4BAAyC;CACxD,MAAM,wBAAQ,IAAI,KAAqB;AAEvC,QAAO;EACN,MAAM,IAAI,KAAqC;AAC9C,UAAO,MAAM,IAAI,IAAI,IAAI;;EAE1B,MAAM,IAAI,KAAa,OAA8B;AACpD,SAAM,IAAI,KAAK,MAAM;;EAEtB,MAAM,KAAK,KAAqC;GAC/C,MAAM,QAAQ,MAAM,IAAI,IAAI,IAAI;AAChC,OAAI,UAAU,KACb,OAAM,OAAO,IAAI;AAElB,UAAO;;EAER,MAAM,OAAO,KAA4B;AACxC,SAAM,OAAO,IAAI;;EAElB"}
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
//#region src/auth-coordination/planner-host.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* A single requirement candidate that a guard submits to the planner-host.
|
|
4
|
-
*
|
|
5
|
-
* Each option describes:
|
|
6
|
-
* 1. What auth requirement it represents (id, kind, label)
|
|
7
|
-
* 2. How to check whether it's already satisfied
|
|
8
|
-
* 3. What to do when the planner selects it as the next pending action
|
|
9
|
-
*/
|
|
10
|
-
interface AuthGuardClientOption {
|
|
11
|
-
/** Unique identifier for this requirement candidate. */
|
|
12
|
-
requirementId: string;
|
|
13
|
-
/**
|
|
14
|
-
* The kind of auth requirement (opaque string).
|
|
15
|
-
* @example "session", "frontend_oidc", "backend_oidc"
|
|
16
|
-
*/
|
|
17
|
-
requirementKind: string;
|
|
18
|
-
/** Human-readable label (for logging / debugging / chooser UI). */
|
|
19
|
-
label?: string;
|
|
20
|
-
/** Arbitrary metadata the adopter can attach. */
|
|
21
|
-
attributes?: Record<string, unknown>;
|
|
22
|
-
/**
|
|
23
|
-
* Check whether this requirement candidate is already authenticated.
|
|
24
|
-
* Called synchronously by the planner-host during evaluation.
|
|
25
|
-
*/
|
|
26
|
-
checkAuthenticated: () => boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Action to execute when this candidate is selected as the pending
|
|
29
|
-
* requirement by the planner-host.
|
|
30
|
-
*
|
|
31
|
-
* Return value semantics:
|
|
32
|
-
* - `true` — allow navigation (requirement will be resolved externally)
|
|
33
|
-
* - `false` — block navigation
|
|
34
|
-
* - `string` — redirect to the given URL
|
|
35
|
-
* - `Promise<...>` — async version of the above
|
|
36
|
-
*/
|
|
37
|
-
onUnauthenticated: () => boolean | string | Promise<boolean | string>;
|
|
38
|
-
}
|
|
39
|
-
/** A flat collection of requirement candidates. */
|
|
40
|
-
interface RequirementsClientSet {
|
|
41
|
-
readonly options: readonly AuthGuardClientOption[];
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* How a child scope's requirements client set relates to its parent.
|
|
45
|
-
*
|
|
46
|
-
* - `inherit` — use the parent's set as-is (child adds nothing)
|
|
47
|
-
* - `merge` — inherit parent's options, then append/override with child's
|
|
48
|
-
* (child options with the same `requirementId` replace parent ones)
|
|
49
|
-
* - `replace` — discard parent's set entirely, use child's set only
|
|
50
|
-
*/
|
|
51
|
-
declare const RequirementsClientSetComposition: {
|
|
52
|
-
readonly Inherit: "inherit";
|
|
53
|
-
readonly Merge: "merge";
|
|
54
|
-
readonly Replace: "replace";
|
|
55
|
-
};
|
|
56
|
-
type RequirementsClientSetComposition = (typeof RequirementsClientSetComposition)[keyof typeof RequirementsClientSetComposition];
|
|
57
|
-
/** A requirements client set annotated with its composition strategy. */
|
|
58
|
-
interface ScopedRequirementsClientSet {
|
|
59
|
-
/** How this set composes with its parent scope. */
|
|
60
|
-
composition: RequirementsClientSetComposition;
|
|
61
|
-
/** The requirement candidates declared at this scope. */
|
|
62
|
-
options: readonly AuthGuardClientOption[];
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Resolve the effective requirements client set by composing a parent set
|
|
66
|
-
* with a child scope's declaration.
|
|
67
|
-
*
|
|
68
|
-
* @param parentOptions - The parent scope's resolved options (or empty).
|
|
69
|
-
* @param child - The child scope's scoped set (with composition strategy).
|
|
70
|
-
* @returns The effective options after composition.
|
|
71
|
-
*/
|
|
72
|
-
declare function resolveEffectiveClientSet(parentOptions: readonly AuthGuardClientOption[], child: ScopedRequirementsClientSet): AuthGuardClientOption[];
|
|
73
|
-
/** Result of a planner-host evaluation. */
|
|
74
|
-
interface PlannerHostResult {
|
|
75
|
-
/** Whether all candidates are authenticated (route can activate). */
|
|
76
|
-
allAuthenticated: boolean;
|
|
77
|
-
/** All candidates that are not yet authenticated. */
|
|
78
|
-
unauthenticatedCandidates: readonly AuthGuardClientOption[];
|
|
79
|
-
/**
|
|
80
|
-
* The candidate selected by the planner as the next one to act on.
|
|
81
|
-
* `null` when `allAuthenticated` is true.
|
|
82
|
-
*
|
|
83
|
-
* Determined by the RequirementPlanner's sequential resolution discipline:
|
|
84
|
-
* the first unresolved requirement in declaration order that is still
|
|
85
|
-
* unauthenticated, then optionally further narrowed by `selectCandidate`.
|
|
86
|
-
*/
|
|
87
|
-
pendingCandidate: AuthGuardClientOption | null;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* A candidate selection strategy.
|
|
91
|
-
*
|
|
92
|
-
* Receives the list of unauthenticated candidates (in RequirementPlanner
|
|
93
|
-
* declaration order) and returns the one that should be acted on next.
|
|
94
|
-
* The default strategy picks the first one (matching the planner's
|
|
95
|
-
* `nextPending` requirement).
|
|
96
|
-
*
|
|
97
|
-
* Async selectors are supported: return a `Promise<AuthGuardClientOption>`
|
|
98
|
-
* to implement interactive chooser UIs (e.g. show a dialog and await the
|
|
99
|
-
* user's pick before navigation continues).
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* ```ts
|
|
103
|
-
* // Async chooser: show a dialog and await user's selection
|
|
104
|
-
* const selectCandidate: CandidateSelector = async (candidates) => {
|
|
105
|
-
* const chosen = await showChooserDialog(candidates);
|
|
106
|
-
* return chosen;
|
|
107
|
-
* };
|
|
108
|
-
* ```
|
|
109
|
-
*/
|
|
110
|
-
type CandidateSelector = (unauthenticated: readonly AuthGuardClientOption[]) => AuthGuardClientOption | Promise<AuthGuardClientOption>;
|
|
111
|
-
/** The planner-host coordination contract. */
|
|
112
|
-
interface PlannerHost {
|
|
113
|
-
/**
|
|
114
|
-
* Evaluate a set of requirement candidates using RequirementPlanner's
|
|
115
|
-
* sequential resolution discipline.
|
|
116
|
-
*
|
|
117
|
-
* Always returns a Promise so that custom async selectors (e.g. chooser
|
|
118
|
-
* dialog) are fully supported. Callers should always `await` the result.
|
|
119
|
-
*
|
|
120
|
-
* @param candidates - The resolved candidates from the guard's client options.
|
|
121
|
-
* @returns Promise resolving to the evaluation result.
|
|
122
|
-
*/
|
|
123
|
-
evaluate(candidates: readonly AuthGuardClientOption[]): Promise<PlannerHostResult>;
|
|
124
|
-
}
|
|
125
|
-
/** Options for {@link createPlannerHost}. */
|
|
126
|
-
interface CreatePlannerHostOptions {
|
|
127
|
-
/**
|
|
128
|
-
* Custom candidate selection strategy.
|
|
129
|
-
*
|
|
130
|
-
* The default strategy picks the candidate that corresponds to the
|
|
131
|
-
* RequirementPlanner's `nextPending` requirement (first unauthenticated
|
|
132
|
-
* in declaration order).
|
|
133
|
-
*
|
|
134
|
-
* A custom strategy can further filter or reorder the unauthenticated
|
|
135
|
-
* candidates, e.g. to implement a chooser UI that lets the user pick.
|
|
136
|
-
*
|
|
137
|
-
* @default first-unauthenticated-matching-planner-nextPending
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```ts
|
|
141
|
-
* // Async chooser: present all options and await user's pick
|
|
142
|
-
* createPlannerHost({
|
|
143
|
-
* selectCandidate: async (candidates) => {
|
|
144
|
-
* return await showChooserDialog(candidates);
|
|
145
|
-
* },
|
|
146
|
-
* })
|
|
147
|
-
* ```
|
|
148
|
-
*/
|
|
149
|
-
selectCandidate?: CandidateSelector;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Create a planner-host instance backed by {@link createRequirementPlanner}.
|
|
153
|
-
*
|
|
154
|
-
* **How it works:**
|
|
155
|
-
*
|
|
156
|
-
* 1. `evaluate()` builds an `AuthRequirement[]` from `candidates`
|
|
157
|
-
* (using each candidate's `requirementId`, `requirementKind`, `label`,
|
|
158
|
-
* and `attributes`).
|
|
159
|
-
* 2. A `RequirementPlanner` is created for this evaluation cycle.
|
|
160
|
-
* 3. Already-authenticated requirements are auto-resolved as `Fulfilled`,
|
|
161
|
-
* respecting the planner's sequential discipline.
|
|
162
|
-
* 4. The planner's `nextPending` determines the first unresolved requirement
|
|
163
|
-
* in declaration order.
|
|
164
|
-
* 5. `selectCandidate` is called with all unauthenticated candidates so
|
|
165
|
-
* adopters can implement custom chooser strategies (e.g. UI dialog).
|
|
166
|
-
* The default strategy picks the first candidate (matching nextPending).
|
|
167
|
-
*
|
|
168
|
-
* `evaluate()` always returns a `Promise` to accommodate async selectors.
|
|
169
|
-
* For synchronous selectors the Promise resolves in the same microtask tick.
|
|
170
|
-
*
|
|
171
|
-
* @example
|
|
172
|
-
* ```ts
|
|
173
|
-
* import { createPlannerHost } from "@securitydept/client/auth-coordination";
|
|
174
|
-
*
|
|
175
|
-
* // Default sequential strategy (sync selector, wrapped in Promise)
|
|
176
|
-
* const host = createPlannerHost();
|
|
177
|
-
* const result = await host.evaluate(candidates);
|
|
178
|
-
*
|
|
179
|
-
* // Async chooser strategy — show a dialog and await user's pick
|
|
180
|
-
* const hostWithChooser = createPlannerHost({
|
|
181
|
-
* selectCandidate: async (candidates) => {
|
|
182
|
-
* return await showChooserDialog(candidates);
|
|
183
|
-
* },
|
|
184
|
-
* });
|
|
185
|
-
* ```
|
|
186
|
-
*/
|
|
187
|
-
declare function createPlannerHost(options?: CreatePlannerHostOptions): PlannerHost;
|
|
188
|
-
//#endregion
|
|
189
|
-
export { PlannerHostResult as a, ScopedRequirementsClientSet as c, PlannerHost as i, createPlannerHost as l, CandidateSelector as n, RequirementsClientSet as o, CreatePlannerHostOptions as r, RequirementsClientSetComposition as s, AuthGuardClientOption as t, resolveEffectiveClientSet as u };
|
|
190
|
-
//# sourceMappingURL=planner-host-CPyGNyQV.d.mts.map
|