@securitydept/client 0.3.0-beta.9 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"router-at5bTdJQ.mjs","names":["defineType","defineType","UriReferenceStringClass"],"sources":["../src/web/events/page-resume.ts","../src/web/page.ts","../src/web/router/router.ts"],"sourcesContent":["import {\n\tdefer,\n\tdistinctUntilChanged,\n\tfilter,\n\tfromEventPattern,\n\tmap,\n\tmerge,\n\ttype Observable,\n} from \"rxjs\";\nimport { type EventStreamTrait } from \"../../events/types\";\nimport { RxEventStream } from \"../../rx\";\n\nexport const PageResumeTriggerKind = {\n\tVisibility: \"visibility\",\n\tPageShow: \"pageshow\",\n\tFocus: \"focus\",\n\tOnline: \"online\",\n} as const;\n\nexport type PageResumeTriggerKind =\n\t(typeof PageResumeTriggerKind)[keyof typeof PageResumeTriggerKind];\n\nexport interface PageResumeEvent {\n\ttrigger: PageResumeTriggerKind;\n\tpersisted?: boolean;\n}\n\nexport interface PageResumeDocumentTarget {\n\taddEventListener(type: \"visibilitychange\", handler: EventListener): void;\n\tremoveEventListener(type: \"visibilitychange\", handler: EventListener): void;\n\tvisibilityState: DocumentVisibilityState;\n}\n\nexport interface PageResumeWindowTarget {\n\taddEventListener(\n\t\ttype: \"pageshow\" | \"focus\" | \"online\",\n\t\thandler: EventListener,\n\t): void;\n\tremoveEventListener(\n\t\ttype: \"pageshow\" | \"focus\" | \"online\",\n\t\thandler: EventListener,\n\t): void;\n}\n\nexport interface CreatePageResumeSourceOptions {\n\tdocumentTarget: PageResumeDocumentTarget | null | undefined;\n\twindowTarget: PageResumeWindowTarget | null | undefined;\n}\n\nexport function createPageResumeSource(\n\toptions: CreatePageResumeSourceOptions,\n): EventStreamTrait<PageResumeEvent> {\n\treturn RxEventStream.fromObservableInput(\n\t\tdefer(() => {\n\t\t\tconst { documentTarget, windowTarget } = options;\n\t\t\tconst streams: Observable<PageResumeEvent>[] = [];\n\n\t\t\tif (documentTarget) {\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) =>\n\t\t\t\t\t\t\tdocumentTarget.addEventListener(\"visibilitychange\", handler),\n\t\t\t\t\t\t(handler) =>\n\t\t\t\t\t\t\tdocumentTarget.removeEventListener(\"visibilitychange\", handler),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tmap(() => documentTarget.visibilityState),\n\t\t\t\t\t\tdistinctUntilChanged(),\n\t\t\t\t\t\tfilter((visibilityState) => visibilityState === \"visible\"),\n\t\t\t\t\t\tmap(() => ({\n\t\t\t\t\t\t\ttrigger: PageResumeTriggerKind.Visibility,\n\t\t\t\t\t\t})),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (windowTarget) {\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) => windowTarget.addEventListener(\"pageshow\", handler),\n\t\t\t\t\t\t(handler) => windowTarget.removeEventListener(\"pageshow\", handler),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tmap((event) => ({\n\t\t\t\t\t\t\ttrigger: PageResumeTriggerKind.PageShow,\n\t\t\t\t\t\t\tpersisted: Boolean((event as PageTransitionEvent).persisted),\n\t\t\t\t\t\t})),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) => windowTarget.addEventListener(\"focus\", handler),\n\t\t\t\t\t\t(handler) => windowTarget.removeEventListener(\"focus\", handler),\n\t\t\t\t\t).pipe(map(() => ({ trigger: PageResumeTriggerKind.Focus }))),\n\t\t\t\t);\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) => windowTarget.addEventListener(\"online\", handler),\n\t\t\t\t\t\t(handler) => windowTarget.removeEventListener(\"online\", handler),\n\t\t\t\t\t).pipe(map(() => ({ trigger: PageResumeTriggerKind.Online }))),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn merge(...streams);\n\t\t}),\n\t);\n}\n","import { type as defineType } from \"arktype\";\nimport { type EnvironmentValidators } from \"../environment/types\";\nimport { type PageLifecycleTrait } from \"../page\";\nimport {\n\tthrowValidationClientError,\n\tvalidateTraitInput,\n\tvalidateWithSchemaSync,\n\ttype WithTraitInputValidator,\n} from \"../validation\";\nimport {\n\tcreatePageResumeSource,\n\ttype PageResumeDocumentTarget,\n\ttype PageResumeWindowTarget,\n} from \"./events\";\n\nexport interface PageLifecycleForNativeWebCreateOptions {\n\tdocument?: PageResumeDocumentTarget | null;\n\twindow?: PageResumeWindowTarget | null;\n}\n\nconst PageResumeDocumentTargetSchema = defineType({\n\taddEventListener: \"Function\",\n\tremoveEventListener: \"Function\",\n\tvisibilityState: \"string\",\n});\n\nconst PageResumeWindowTargetSchema = defineType({\n\taddEventListener: \"Function\",\n\tremoveEventListener: \"Function\",\n});\n\nconst PageLifecycleForNativeWebUnavailableProbeSchema = defineType({\n\tdocument: \"null | undefined\",\n\twindow: \"null | undefined\",\n});\n\nconst PageLifecycleForNativeWebCreateOptionsSchema = defineType({\n\tdocument: PageResumeDocumentTargetSchema.or(\"null\").or(\"undefined\"),\n\twindow: PageResumeWindowTargetSchema.or(\"null\").or(\"undefined\"),\n});\n\nexport function createPageLifecycleForNativeWeb(\n\toptions: PageLifecycleForNativeWebCreateOptions &\n\t\tWithTraitInputValidator<Pick<EnvironmentValidators, \"pageLifecycle\">> = {},\n): PageLifecycleTrait | null {\n\tconst { validators, ...createOptions } = options;\n\tconst global = globalThis as {\n\t\tdocument?: PageResumeDocumentTarget;\n\t\twindow?: PageResumeWindowTarget;\n\t};\n\tconst resolvedCreateOptions = {\n\t\tdocument: global.document ?? null,\n\t\twindow: global.window ?? null,\n\t\t...createOptions,\n\t};\n\tconst unavailableProbeResult = validateWithSchemaSync(\n\t\tPageLifecycleForNativeWebUnavailableProbeSchema,\n\t\tresolvedCreateOptions,\n\t);\n\tif (unavailableProbeResult.success) {\n\t\treturn null;\n\t}\n\tvalidateTraitInput({\n\t\tvalue: resolvedCreateOptions,\n\t\tbundledSchema: PageLifecycleForNativeWebCreateOptionsSchema,\n\t\tvalidator: validators?.pageLifecycle,\n\t\tonInvalid: (failure) =>\n\t\t\tthrowValidationClientError({\n\t\t\t\tcode: \"web.page.invalid_native_web_page_lifecycle_options\",\n\t\t\t\tsource: \"web\",\n\t\t\t\tmessagePrefix:\n\t\t\t\t\t\"createPageLifecycleForNativeWeb could not validate pageLifecycleForNativeWebCreateOptions\",\n\t\t\t\tfailure,\n\t\t\t}),\n\t});\n\tconst documentTarget = resolvedCreateOptions.document ?? null;\n\tconst windowTarget = resolvedCreateOptions.window ?? null;\n\treturn {\n\t\tresume: createPageResumeSource({\n\t\t\tdocumentTarget,\n\t\t\twindowTarget,\n\t\t}),\n\t};\n}\n","import { type as defineType } from \"arktype\";\nimport { type EnvironmentValidators } from \"../../environment/types\";\nimport { ClientError, ClientErrorKind } from \"../../errors\";\nimport {\n\tRouterNavigationMode,\n\ttype RouterNavigationRequest,\n\ttype RouterTrait,\n} from \"../../router\";\nimport {\n\ttype UriReferenceString,\n\tUriReferenceString as UriReferenceStringClass,\n} from \"../../struct/uri-string\";\nimport {\n\tthrowValidationClientError,\n\tvalidateTraitInput,\n\tvalidateWithSchemaSync,\n\ttype WithTraitInputValidator,\n} from \"../../validation\";\n\nexport interface NativeWebNavigateEventLike {\n\treadonly destination?: {\n\t\treadonly url: string;\n\t\tgetState?(): unknown;\n\t};\n\treadonly navigationType?: \"push\" | \"replace\" | \"reload\" | \"traverse\";\n\treadonly canIntercept?: boolean;\n\treadonly signal?: AbortSignal;\n\tintercept(options?: { handler?: () => Promise<void> | void }): void;\n\tredirect?(url: string, options?: { history?: \"push\" | \"replace\" }): void;\n}\n\nexport interface NativeWebNavigationLike {\n\tnavigate(\n\t\turl: string,\n\t\toptions?: { history?: \"push\" | \"replace\"; state?: unknown },\n\t): { committed?: Promise<unknown>; finished?: Promise<unknown> } | void;\n\taddEventListener?(\n\t\ttype: \"navigate\",\n\t\thandler: (event: NativeWebNavigateEventLike) => void,\n\t): void;\n\tremoveEventListener?(\n\t\ttype: \"navigate\",\n\t\thandler: (event: NativeWebNavigateEventLike) => void,\n\t): void;\n}\n\nexport interface NativeWebLocationLike {\n\thref: string;\n\thash?: string;\n\tpathname?: string;\n\tsearch?: string;\n\torigin?: string;\n}\n\nexport interface NativeWebHistoryLike {\n\tpushState(data: unknown, unused: string, url?: string | URL | null): void;\n\treplaceState(data: unknown, unused: string, url?: string | URL | null): void;\n}\n\nexport interface NativeWebWindowLike {\n\tlocation?: NativeWebLocationLike;\n\thistory?: NativeWebHistoryLike;\n}\n\nexport interface RouterForNativeWebCreateOptions {\n\tnavigation?: NativeWebNavigationLike | null;\n\tlocation?: NativeWebLocationLike | null;\n\thistory?: NativeWebHistoryLike | null;\n\twindow?: NativeWebWindowLike | null;\n}\n\nexport interface ResolvedRouterForNativeWebCreateOptions {\n\tnavigation: NativeWebNavigationLike | null;\n\tlocation: NativeWebLocationLike | null;\n\thistory: NativeWebHistoryLike | null;\n\twindow: NativeWebWindowLike | null;\n}\n\nconst NativeWebNavigationLikeSchema = defineType({\n\tnavigate: \"Function\",\n\taddEventListener: \"Function?\",\n\tremoveEventListener: \"Function?\",\n});\n\nconst NativeWebLocationLikeSchema = defineType({\n\thref: \"string\",\n});\n\nconst NativeWebHistoryLikeSchema = defineType({\n\tpushState: \"Function\",\n\treplaceState: \"Function\",\n});\n\nconst NativeWebWindowLikeSchema = defineType({\n\tlocation: NativeWebLocationLikeSchema.optional(),\n\thistory: NativeWebHistoryLikeSchema.optional(),\n\topen: \"Function?\",\n});\n\nconst NullableNativeWebHistoryLikeSchema =\n\tNativeWebHistoryLikeSchema.or(\"null\").or(\"undefined\");\nconst NullableNativeWebWindowLikeSchema =\n\tNativeWebWindowLikeSchema.or(\"null\").or(\"undefined\");\n\nconst RouterForNativeWebCreateOptionsSchema = defineType({\n\tnavigation: NativeWebNavigationLikeSchema,\n\tlocation: NativeWebLocationLikeSchema.or(\"null\").or(\"undefined\"),\n\thistory: NullableNativeWebHistoryLikeSchema,\n\twindow: NullableNativeWebWindowLikeSchema,\n}).or({\n\tnavigation: \"null | undefined\",\n\tlocation: NativeWebLocationLikeSchema,\n\thistory: NullableNativeWebHistoryLikeSchema,\n\twindow: NullableNativeWebWindowLikeSchema,\n});\n\nconst RouterForNativeWebUnavailableProbeSchema = defineType({\n\tnavigation: \"null | undefined\",\n\tlocation: \"null | undefined\",\n\thistory: \"null | undefined\",\n\twindow: \"null | undefined\",\n});\n\nexport function createRouterForNativeWeb(\n\toptions: RouterForNativeWebCreateOptions &\n\t\tWithTraitInputValidator<Pick<EnvironmentValidators, \"router\">> = {},\n): RouterTrait | null {\n\tconst resolvedCreateOptions = resolveRouterForNativeWebCreateOptions(options);\n\tif (\n\t\tvalidateWithSchemaSync(\n\t\t\tRouterForNativeWebUnavailableProbeSchema,\n\t\t\tresolvedCreateOptions,\n\t\t).success\n\t) {\n\t\treturn null;\n\t}\n\tvalidateTraitInput({\n\t\tvalue: resolvedCreateOptions,\n\t\tbundledSchema: RouterForNativeWebCreateOptionsSchema,\n\t\tvalidator: options.validators?.router,\n\t\tonInvalid: (failure) =>\n\t\t\tthrowValidationClientError({\n\t\t\t\tcode: \"web.router.invalid_native_web_router_options\",\n\t\t\t\tsource: \"web\",\n\t\t\t\tmessagePrefix:\n\t\t\t\t\t\"createRouterForNativeWeb could not validate routerForNativeWebCreateOptions\",\n\t\t\t\tfailure,\n\t\t\t}),\n\t});\n\tconst router = new NativeWebRouter(resolvedCreateOptions);\n\treturn {\n\t\tcurrentUrl() {\n\t\t\treturn router.currentUrl();\n\t\t},\n\t\tnavigate(request) {\n\t\t\treturn router.navigate(request);\n\t\t},\n\t};\n}\n\nexport class NativeWebRouter implements RouterTrait {\n\tprotected readonly router: WebNavigationRouter | WebLegacyRouter;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tthis.router = options.navigation\n\t\t\t? new WebNavigationRouter(options)\n\t\t\t: new WebLegacyRouter(options);\n\t}\n\n\tcurrentUrl(): UriReferenceString | null {\n\t\treturn this.router.currentUrl();\n\t}\n\n\tnavigate(request: RouterNavigationRequest): void | Promise<void> {\n\t\treturn this.router.navigate(request);\n\t}\n}\n\nabstract class NativeWebRouterBase implements RouterTrait {\n\tprotected readonly location: NativeWebLocationLike | null;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tthis.location = options.location;\n\t}\n\n\tcurrentUrl(): UriReferenceString | null {\n\t\treturn this.location?.href\n\t\t\t? UriReferenceStringClass.parse(this.location.href)\n\t\t\t: null;\n\t}\n\n\tprotected resolveNavigationTarget(request: RouterNavigationRequest): string {\n\t\treturn request.url.toString();\n\t}\n\n\tabstract navigate(request: RouterNavigationRequest): void | Promise<void>;\n}\n\nexport class WebNavigationRouter extends NativeWebRouterBase {\n\tprotected readonly navigation: NativeWebNavigationLike;\n\tprotected readonly history: NativeWebHistoryLike | null;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tif (!options.navigation) {\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.navigation_unavailable\",\n\t\t\t\tmessage: \"WebNavigationRouter requires the Navigation API\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\tsuper(options);\n\t\tthis.navigation = options.navigation;\n\t\tthis.history = options.history;\n\t}\n\n\tasync navigate(request: RouterNavigationRequest): Promise<void> {\n\t\tconst target = this.resolveNavigationTarget(request);\n\t\tif (request.mode === RouterNavigationMode.External) {\n\t\t\tif (this.location) {\n\t\t\t\tthis.location.href = target;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.location_unavailable\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Native web router cannot perform external navigation without location\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\t// Prefer History API for same-origin Push/Replace. Unintercepted\n\t\t// Navigation API navigations load a new document even for in-app path,\n\t\t// query, or hash changes, which breaks SPA routing and aborts in-flight\n\t\t// OIDC callback handling after the callback payload has been taken.\n\t\tif (this.history && this.isSameOriginNavigation(request.url)) {\n\t\t\tif (request.mode === RouterNavigationMode.Replace) {\n\t\t\t\tthis.history.replaceState(request.state ?? null, \"\", target);\n\t\t\t} else {\n\t\t\t\tthis.history.pushState(request.state ?? null, \"\", target);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst result = this.navigation.navigate(target, {\n\t\t\thistory:\n\t\t\t\trequest.mode === RouterNavigationMode.Replace\n\t\t\t\t\t? RouterNavigationMode.Replace\n\t\t\t\t\t: RouterNavigationMode.Push,\n\t\t\tstate: request.state,\n\t\t});\n\t\tawait result?.committed;\n\t}\n\n\tprivate isSameOriginNavigation(url: UriReferenceString): boolean {\n\t\tconst current = this.currentUrl();\n\t\tif (!current) {\n\t\t\treturn false;\n\t\t}\n\t\tif (url.isAbsolute() && current.isAbsolute()) {\n\t\t\treturn url.origin === current.origin;\n\t\t}\n\t\t// Relative targets inherit the current document origin.\n\t\treturn url.isRelative();\n\t}\n}\n\nexport class WebLegacyRouter extends NativeWebRouterBase {\n\tprotected readonly history: NativeWebHistoryLike | null;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tsuper(options);\n\t\tthis.history = options.history;\n\t}\n\n\tasync navigate(request: RouterNavigationRequest): Promise<void> {\n\t\tconst target = this.resolveNavigationTarget(request);\n\t\tif (request.mode === RouterNavigationMode.External) {\n\t\t\tif (this.location) {\n\t\t\t\tthis.location.href = target;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.location_unavailable\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Native web router cannot perform external navigation without location\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\tif (!this.history) {\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.history_unavailable\",\n\t\t\t\tmessage: \"Native web router requires history for in-page navigation\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\tif (request.mode === RouterNavigationMode.Replace) {\n\t\t\tthis.history.replaceState(request.state ?? null, \"\", target);\n\t\t} else {\n\t\t\tthis.history.pushState(request.state ?? null, \"\", target);\n\t\t}\n\t}\n}\n\nexport function resolveRouterForNativeWebCreateOptions(\n\toptions: RouterForNativeWebCreateOptions = {},\n): ResolvedRouterForNativeWebCreateOptions {\n\tconst global = globalThis as {\n\t\tnavigation?: NativeWebNavigationLike;\n\t\tlocation?: NativeWebLocationLike;\n\t\thistory?: NativeWebHistoryLike;\n\t\twindow?: NativeWebWindowLike;\n\t};\n\tconst windowLike = Object.hasOwn(options, \"window\")\n\t\t? (options.window ?? null)\n\t\t: (global.window ?? null);\n\tconst navigation = Object.hasOwn(options, \"navigation\")\n\t\t? (options.navigation ?? null)\n\t\t: (global.navigation ?? null);\n\tconst location = Object.hasOwn(options, \"location\")\n\t\t? (options.location ?? null)\n\t\t: (windowLike?.location ?? global.location ?? null);\n\tconst history = Object.hasOwn(options, \"history\")\n\t\t? (options.history ?? null)\n\t\t: (windowLike?.history ?? global.history ?? null);\n\treturn {\n\t\twindow: windowLike,\n\t\tnavigation,\n\t\tlocation,\n\t\thistory,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"router-BawAJQ1s.mjs","names":["defineType","defineType","UriReferenceStringClass"],"sources":["../src/web/events/page-resume.ts","../src/web/page.ts","../src/web/router/router.ts"],"sourcesContent":["import {\n\tdefer,\n\tdistinctUntilChanged,\n\tfilter,\n\tfromEventPattern,\n\tmap,\n\tmerge,\n\ttype Observable,\n} from \"rxjs\";\nimport { type EventStreamTrait } from \"../../events/types\";\nimport { RxEventStream } from \"../../rx\";\n\nexport const PageResumeTriggerKind = {\n\tVisibility: \"visibility\",\n\tPageShow: \"pageshow\",\n\tFocus: \"focus\",\n\tOnline: \"online\",\n} as const;\n\nexport type PageResumeTriggerKind =\n\t(typeof PageResumeTriggerKind)[keyof typeof PageResumeTriggerKind];\n\nexport interface PageResumeEvent {\n\ttrigger: PageResumeTriggerKind;\n\tpersisted?: boolean;\n}\n\nexport interface PageResumeDocumentTarget {\n\taddEventListener(type: \"visibilitychange\", handler: EventListener): void;\n\tremoveEventListener(type: \"visibilitychange\", handler: EventListener): void;\n\tvisibilityState: DocumentVisibilityState;\n}\n\nexport interface PageResumeWindowTarget {\n\taddEventListener(\n\t\ttype: \"pageshow\" | \"focus\" | \"online\",\n\t\thandler: EventListener,\n\t): void;\n\tremoveEventListener(\n\t\ttype: \"pageshow\" | \"focus\" | \"online\",\n\t\thandler: EventListener,\n\t): void;\n}\n\nexport interface CreatePageResumeSourceOptions {\n\tdocumentTarget: PageResumeDocumentTarget | null | undefined;\n\twindowTarget: PageResumeWindowTarget | null | undefined;\n}\n\nexport function createPageResumeSource(\n\toptions: CreatePageResumeSourceOptions,\n): EventStreamTrait<PageResumeEvent> {\n\treturn RxEventStream.fromObservableInput(\n\t\tdefer(() => {\n\t\t\tconst { documentTarget, windowTarget } = options;\n\t\t\tconst streams: Observable<PageResumeEvent>[] = [];\n\n\t\t\tif (documentTarget) {\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) =>\n\t\t\t\t\t\t\tdocumentTarget.addEventListener(\"visibilitychange\", handler),\n\t\t\t\t\t\t(handler) =>\n\t\t\t\t\t\t\tdocumentTarget.removeEventListener(\"visibilitychange\", handler),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tmap(() => documentTarget.visibilityState),\n\t\t\t\t\t\tdistinctUntilChanged(),\n\t\t\t\t\t\tfilter((visibilityState) => visibilityState === \"visible\"),\n\t\t\t\t\t\tmap(() => ({\n\t\t\t\t\t\t\ttrigger: PageResumeTriggerKind.Visibility,\n\t\t\t\t\t\t})),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (windowTarget) {\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) => windowTarget.addEventListener(\"pageshow\", handler),\n\t\t\t\t\t\t(handler) => windowTarget.removeEventListener(\"pageshow\", handler),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tmap((event) => ({\n\t\t\t\t\t\t\ttrigger: PageResumeTriggerKind.PageShow,\n\t\t\t\t\t\t\tpersisted: Boolean((event as PageTransitionEvent).persisted),\n\t\t\t\t\t\t})),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) => windowTarget.addEventListener(\"focus\", handler),\n\t\t\t\t\t\t(handler) => windowTarget.removeEventListener(\"focus\", handler),\n\t\t\t\t\t).pipe(map(() => ({ trigger: PageResumeTriggerKind.Focus }))),\n\t\t\t\t);\n\t\t\t\tstreams.push(\n\t\t\t\t\tfromEventPattern<Event>(\n\t\t\t\t\t\t(handler) => windowTarget.addEventListener(\"online\", handler),\n\t\t\t\t\t\t(handler) => windowTarget.removeEventListener(\"online\", handler),\n\t\t\t\t\t).pipe(map(() => ({ trigger: PageResumeTriggerKind.Online }))),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn merge(...streams);\n\t\t}),\n\t);\n}\n","import { type as defineType } from \"arktype\";\nimport { type EnvironmentValidators } from \"../environment/types\";\nimport { type PageLifecycleTrait } from \"../page\";\nimport {\n\tthrowValidationClientError,\n\tvalidateTraitInput,\n\tvalidateWithSchemaSync,\n\ttype WithTraitInputValidator,\n} from \"../validation\";\nimport {\n\tcreatePageResumeSource,\n\ttype PageResumeDocumentTarget,\n\ttype PageResumeWindowTarget,\n} from \"./events\";\n\nexport interface PageLifecycleForNativeWebCreateOptions {\n\tdocument?: PageResumeDocumentTarget | null;\n\twindow?: PageResumeWindowTarget | null;\n}\n\nconst PageResumeDocumentTargetSchema = defineType({\n\taddEventListener: \"Function\",\n\tremoveEventListener: \"Function\",\n\tvisibilityState: \"string\",\n});\n\nconst PageResumeWindowTargetSchema = defineType({\n\taddEventListener: \"Function\",\n\tremoveEventListener: \"Function\",\n});\n\nconst PageLifecycleForNativeWebUnavailableProbeSchema = defineType({\n\tdocument: \"null | undefined\",\n\twindow: \"null | undefined\",\n});\n\nconst PageLifecycleForNativeWebCreateOptionsSchema = defineType({\n\tdocument: PageResumeDocumentTargetSchema.or(\"null\").or(\"undefined\"),\n\twindow: PageResumeWindowTargetSchema.or(\"null\").or(\"undefined\"),\n});\n\nexport function createPageLifecycleForNativeWeb(\n\toptions: PageLifecycleForNativeWebCreateOptions &\n\t\tWithTraitInputValidator<Pick<EnvironmentValidators, \"pageLifecycle\">> = {},\n): PageLifecycleTrait | null {\n\tconst { validators, ...createOptions } = options;\n\tconst global = globalThis as {\n\t\tdocument?: PageResumeDocumentTarget;\n\t\twindow?: PageResumeWindowTarget;\n\t};\n\tconst resolvedCreateOptions = {\n\t\tdocument: global.document ?? null,\n\t\twindow: global.window ?? null,\n\t\t...createOptions,\n\t};\n\tconst unavailableProbeResult = validateWithSchemaSync(\n\t\tPageLifecycleForNativeWebUnavailableProbeSchema,\n\t\tresolvedCreateOptions,\n\t);\n\tif (unavailableProbeResult.success) {\n\t\treturn null;\n\t}\n\tvalidateTraitInput({\n\t\tvalue: resolvedCreateOptions,\n\t\tbundledSchema: PageLifecycleForNativeWebCreateOptionsSchema,\n\t\tvalidator: validators?.pageLifecycle,\n\t\tonInvalid: (failure) =>\n\t\t\tthrowValidationClientError({\n\t\t\t\tcode: \"web.page.invalid_native_web_page_lifecycle_options\",\n\t\t\t\tsource: \"web\",\n\t\t\t\tmessagePrefix:\n\t\t\t\t\t\"createPageLifecycleForNativeWeb could not validate pageLifecycleForNativeWebCreateOptions\",\n\t\t\t\tfailure,\n\t\t\t}),\n\t});\n\tconst documentTarget = resolvedCreateOptions.document ?? null;\n\tconst windowTarget = resolvedCreateOptions.window ?? null;\n\treturn {\n\t\tresume: createPageResumeSource({\n\t\t\tdocumentTarget,\n\t\t\twindowTarget,\n\t\t}),\n\t};\n}\n","import { type as defineType } from \"arktype\";\nimport { type EnvironmentValidators } from \"../../environment/types\";\nimport { ClientError, ClientErrorKind } from \"../../errors\";\nimport {\n\tRouterNavigationMode,\n\ttype RouterNavigationRequest,\n\ttype RouterTrait,\n} from \"../../router\";\nimport {\n\ttype UriReferenceString,\n\tUriReferenceString as UriReferenceStringClass,\n} from \"../../struct/uri-string\";\nimport {\n\tthrowValidationClientError,\n\tvalidateTraitInput,\n\tvalidateWithSchemaSync,\n\ttype WithTraitInputValidator,\n} from \"../../validation\";\n\nexport interface NativeWebNavigateEventLike {\n\treadonly destination?: {\n\t\treadonly url: string;\n\t\tgetState?(): unknown;\n\t};\n\treadonly navigationType?: \"push\" | \"replace\" | \"reload\" | \"traverse\";\n\treadonly canIntercept?: boolean;\n\treadonly signal?: AbortSignal;\n\tintercept(options?: { handler?: () => Promise<void> | void }): void;\n\tredirect?(url: string, options?: { history?: \"push\" | \"replace\" }): void;\n}\n\nexport interface NativeWebNavigationLike {\n\tnavigate(\n\t\turl: string,\n\t\toptions?: { history?: \"push\" | \"replace\"; state?: unknown },\n\t): { committed?: Promise<unknown>; finished?: Promise<unknown> } | void;\n\taddEventListener?(\n\t\ttype: \"navigate\",\n\t\thandler: (event: NativeWebNavigateEventLike) => void,\n\t): void;\n\tremoveEventListener?(\n\t\ttype: \"navigate\",\n\t\thandler: (event: NativeWebNavigateEventLike) => void,\n\t): void;\n}\n\nexport interface NativeWebLocationLike {\n\thref: string;\n\thash?: string;\n\tpathname?: string;\n\tsearch?: string;\n\torigin?: string;\n}\n\nexport interface NativeWebHistoryLike {\n\tpushState(data: unknown, unused: string, url?: string | URL | null): void;\n\treplaceState(data: unknown, unused: string, url?: string | URL | null): void;\n}\n\nexport interface NativeWebWindowLike {\n\tlocation?: NativeWebLocationLike;\n\thistory?: NativeWebHistoryLike;\n}\n\nexport interface RouterForNativeWebCreateOptions {\n\tnavigation?: NativeWebNavigationLike | null;\n\tlocation?: NativeWebLocationLike | null;\n\thistory?: NativeWebHistoryLike | null;\n\twindow?: NativeWebWindowLike | null;\n}\n\nexport interface ResolvedRouterForNativeWebCreateOptions {\n\tnavigation: NativeWebNavigationLike | null;\n\tlocation: NativeWebLocationLike | null;\n\thistory: NativeWebHistoryLike | null;\n\twindow: NativeWebWindowLike | null;\n}\n\nconst NativeWebNavigationLikeSchema = defineType({\n\tnavigate: \"Function\",\n\taddEventListener: \"Function?\",\n\tremoveEventListener: \"Function?\",\n});\n\nconst NativeWebLocationLikeSchema = defineType({\n\thref: \"string\",\n});\n\nconst NativeWebHistoryLikeSchema = defineType({\n\tpushState: \"Function\",\n\treplaceState: \"Function\",\n});\n\nconst NativeWebWindowLikeSchema = defineType({\n\tlocation: NativeWebLocationLikeSchema.optional(),\n\thistory: NativeWebHistoryLikeSchema.optional(),\n\topen: \"Function?\",\n});\n\nconst NullableNativeWebHistoryLikeSchema =\n\tNativeWebHistoryLikeSchema.or(\"null\").or(\"undefined\");\nconst NullableNativeWebWindowLikeSchema =\n\tNativeWebWindowLikeSchema.or(\"null\").or(\"undefined\");\n\nconst RouterForNativeWebCreateOptionsSchema = defineType({\n\tnavigation: NativeWebNavigationLikeSchema,\n\tlocation: NativeWebLocationLikeSchema.or(\"null\").or(\"undefined\"),\n\thistory: NullableNativeWebHistoryLikeSchema,\n\twindow: NullableNativeWebWindowLikeSchema,\n}).or({\n\tnavigation: \"null | undefined\",\n\tlocation: NativeWebLocationLikeSchema,\n\thistory: NullableNativeWebHistoryLikeSchema,\n\twindow: NullableNativeWebWindowLikeSchema,\n});\n\nconst RouterForNativeWebUnavailableProbeSchema = defineType({\n\tnavigation: \"null | undefined\",\n\tlocation: \"null | undefined\",\n\thistory: \"null | undefined\",\n\twindow: \"null | undefined\",\n});\n\nexport function createRouterForNativeWeb(\n\toptions: RouterForNativeWebCreateOptions &\n\t\tWithTraitInputValidator<Pick<EnvironmentValidators, \"router\">> = {},\n): RouterTrait | null {\n\tconst resolvedCreateOptions = resolveRouterForNativeWebCreateOptions(options);\n\tif (\n\t\tvalidateWithSchemaSync(\n\t\t\tRouterForNativeWebUnavailableProbeSchema,\n\t\t\tresolvedCreateOptions,\n\t\t).success\n\t) {\n\t\treturn null;\n\t}\n\tvalidateTraitInput({\n\t\tvalue: resolvedCreateOptions,\n\t\tbundledSchema: RouterForNativeWebCreateOptionsSchema,\n\t\tvalidator: options.validators?.router,\n\t\tonInvalid: (failure) =>\n\t\t\tthrowValidationClientError({\n\t\t\t\tcode: \"web.router.invalid_native_web_router_options\",\n\t\t\t\tsource: \"web\",\n\t\t\t\tmessagePrefix:\n\t\t\t\t\t\"createRouterForNativeWeb could not validate routerForNativeWebCreateOptions\",\n\t\t\t\tfailure,\n\t\t\t}),\n\t});\n\tconst router = new NativeWebRouter(resolvedCreateOptions);\n\treturn {\n\t\tcurrentUrl() {\n\t\t\treturn router.currentUrl();\n\t\t},\n\t\tnavigate(request) {\n\t\t\treturn router.navigate(request);\n\t\t},\n\t};\n}\n\nexport class NativeWebRouter implements RouterTrait {\n\tprotected readonly router: WebNavigationRouter | WebLegacyRouter;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tthis.router = options.navigation\n\t\t\t? new WebNavigationRouter(options)\n\t\t\t: new WebLegacyRouter(options);\n\t}\n\n\tcurrentUrl(): UriReferenceString | null {\n\t\treturn this.router.currentUrl();\n\t}\n\n\tnavigate(request: RouterNavigationRequest): void | Promise<void> {\n\t\treturn this.router.navigate(request);\n\t}\n}\n\nabstract class NativeWebRouterBase implements RouterTrait {\n\tprotected readonly location: NativeWebLocationLike | null;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tthis.location = options.location;\n\t}\n\n\tcurrentUrl(): UriReferenceString | null {\n\t\treturn this.location?.href\n\t\t\t? UriReferenceStringClass.parse(this.location.href)\n\t\t\t: null;\n\t}\n\n\tprotected resolveNavigationTarget(request: RouterNavigationRequest): string {\n\t\treturn request.url.toString();\n\t}\n\n\tabstract navigate(request: RouterNavigationRequest): void | Promise<void>;\n}\n\nexport class WebNavigationRouter extends NativeWebRouterBase {\n\tprotected readonly navigation: NativeWebNavigationLike;\n\tprotected readonly history: NativeWebHistoryLike | null;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tif (!options.navigation) {\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.navigation_unavailable\",\n\t\t\t\tmessage: \"WebNavigationRouter requires the Navigation API\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\tsuper(options);\n\t\tthis.navigation = options.navigation;\n\t\tthis.history = options.history;\n\t}\n\n\tasync navigate(request: RouterNavigationRequest): Promise<void> {\n\t\tconst target = this.resolveNavigationTarget(request);\n\t\tif (request.mode === RouterNavigationMode.External) {\n\t\t\tif (this.location) {\n\t\t\t\tthis.location.href = target;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.location_unavailable\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Native web router cannot perform external navigation without location\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\t// Prefer History API for same-origin Push/Replace. Unintercepted\n\t\t// Navigation API navigations load a new document even for in-app path,\n\t\t// query, or hash changes, which breaks SPA routing and aborts in-flight\n\t\t// OIDC callback handling after the callback payload has been taken.\n\t\tif (this.history && this.isSameOriginNavigation(request.url)) {\n\t\t\tif (request.mode === RouterNavigationMode.Replace) {\n\t\t\t\tthis.history.replaceState(request.state ?? null, \"\", target);\n\t\t\t} else {\n\t\t\t\tthis.history.pushState(request.state ?? null, \"\", target);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst result = this.navigation.navigate(target, {\n\t\t\thistory:\n\t\t\t\trequest.mode === RouterNavigationMode.Replace\n\t\t\t\t\t? RouterNavigationMode.Replace\n\t\t\t\t\t: RouterNavigationMode.Push,\n\t\t\tstate: request.state,\n\t\t});\n\t\tawait result?.committed;\n\t}\n\n\tprivate isSameOriginNavigation(url: UriReferenceString): boolean {\n\t\tconst current = this.currentUrl();\n\t\tif (!current) {\n\t\t\treturn false;\n\t\t}\n\t\tif (url.isAbsolute() && current.isAbsolute()) {\n\t\t\treturn url.origin === current.origin;\n\t\t}\n\t\t// Relative targets inherit the current document origin.\n\t\treturn url.isRelative();\n\t}\n}\n\nexport class WebLegacyRouter extends NativeWebRouterBase {\n\tprotected readonly history: NativeWebHistoryLike | null;\n\n\tconstructor(options: ResolvedRouterForNativeWebCreateOptions) {\n\t\tsuper(options);\n\t\tthis.history = options.history;\n\t}\n\n\tasync navigate(request: RouterNavigationRequest): Promise<void> {\n\t\tconst target = this.resolveNavigationTarget(request);\n\t\tif (request.mode === RouterNavigationMode.External) {\n\t\t\tif (this.location) {\n\t\t\t\tthis.location.href = target;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.location_unavailable\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Native web router cannot perform external navigation without location\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\tif (!this.history) {\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: \"web.router.history_unavailable\",\n\t\t\t\tmessage: \"Native web router requires history for in-page navigation\",\n\t\t\t\tsource: \"web.router\",\n\t\t\t});\n\t\t}\n\t\tif (request.mode === RouterNavigationMode.Replace) {\n\t\t\tthis.history.replaceState(request.state ?? null, \"\", target);\n\t\t} else {\n\t\t\tthis.history.pushState(request.state ?? null, \"\", target);\n\t\t}\n\t}\n}\n\nexport function resolveRouterForNativeWebCreateOptions(\n\toptions: RouterForNativeWebCreateOptions = {},\n): ResolvedRouterForNativeWebCreateOptions {\n\tconst global = globalThis as {\n\t\tnavigation?: NativeWebNavigationLike;\n\t\tlocation?: NativeWebLocationLike;\n\t\thistory?: NativeWebHistoryLike;\n\t\twindow?: NativeWebWindowLike;\n\t};\n\tconst windowLike = Object.hasOwn(options, \"window\")\n\t\t? (options.window ?? null)\n\t\t: (global.window ?? null);\n\tconst navigation = Object.hasOwn(options, \"navigation\")\n\t\t? (options.navigation ?? null)\n\t\t: (global.navigation ?? null);\n\tconst location = Object.hasOwn(options, \"location\")\n\t\t? (options.location ?? null)\n\t\t: (windowLike?.location ?? global.location ?? null);\n\tconst history = Object.hasOwn(options, \"history\")\n\t\t? (options.history ?? null)\n\t\t: (windowLike?.history ?? global.history ?? null);\n\treturn {\n\t\twindow: windowLike,\n\t\tnavigation,\n\t\tlocation,\n\t\thistory,\n\t};\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { F as ResourceSnapshot, I as ResourceStatus, L as ResourceTrait, T as TimeTrait, _ as RxEventStream, a as resourceFromSnapshots, c as RxComputedSignalCompat, d as RxSignalWatchCanceller, f as RxSignalWatchOptions, g as RxEventReplaySubject, h as RxStateSignalCompat, i as mapResource, l as RxSignalDirtyEvent, m as RxStateSignal, n as RxResourceOptions, o as rxResource, p as RxSignalWatchScheduler, r as RxResourceStreamContext, s as RxComputedSignal, t as RxResource, u as RxSignalOptions, v as RxEventSubject } from "../index-CFAJ969E.mjs";
1
+ import { F as ResourceSnapshot, I as ResourceStatus, L as ResourceTrait, T as TimeTrait, _ as RxEventStream, a as resourceFromSnapshots, c as RxComputedSignalCompat, d as RxSignalDirtyEvent, f as RxSignalOptions, g as RxEventReplaySubject, h as RxSignalWatchScheduler, i as mapResource, l as RxStateSignal, m as RxSignalWatchOptions, n as RxResourceOptions, o as rxResource, p as RxSignalWatchCanceller, r as RxResourceStreamContext, s as RxComputedSignal, t as RxResource, u as RxStateSignalCompat, v as RxEventSubject } from "../index-_1lhMnf9.mjs";
2
2
  import { Observable, ObservableInput, Observer, OperatorFunction } from "rxjs";
3
3
  import { AsyncScheduler } from "rxjs/internal/scheduler/AsyncScheduler";
4
4
  //#region src/rx/command.d.ts
package/dist/rx/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { A as RxEventSubject, C as exhaustCommand, D as RxStateSignal, E as RxComputedSignal, O as RxEventReplaySubject, S as dispatchCommandLocallyToStream, T as unwrapCommandTerminalResponse, _ as commandResponseData, b as dispatchCommandByIdToStream, g as CommandResponseType, h as createAsyncSchedulerWithTimestampProvider, i as rxResource, k as RxEventStream, l as ResourceStatus, n as mapResource, r as resourceFromSnapshots, t as RxResource, v as concatCommand, w as switchCommand, x as dispatchCommandLocallyToPromise, y as dispatchCommandByIdToPromise } from "../rx-DM6Ouv-m.mjs";
1
+ import { A as RxEventSubject, C as exhaustCommand, D as RxStateSignal, E as RxComputedSignal, O as RxEventReplaySubject, S as dispatchCommandLocallyToStream, T as unwrapCommandTerminalResponse, _ as commandResponseData, b as dispatchCommandByIdToStream, g as CommandResponseType, h as createAsyncSchedulerWithTimestampProvider, i as rxResource, k as RxEventStream, l as ResourceStatus, n as mapResource, r as resourceFromSnapshots, t as RxResource, v as concatCommand, w as switchCommand, x as dispatchCommandLocallyToPromise, y as dispatchCommandByIdToPromise } from "../rx-82t7QNQL.mjs";
2
2
  export { CommandResponseType, ResourceStatus, RxComputedSignal, RxEventReplaySubject, RxEventStream, RxEventSubject, RxResource, RxStateSignal, commandResponseData, concatCommand, createAsyncSchedulerWithTimestampProvider, dispatchCommandByIdToPromise, dispatchCommandByIdToStream, dispatchCommandLocallyToPromise, dispatchCommandLocallyToStream, exhaustCommand, mapResource, resourceFromSnapshots, rxResource, switchCommand, unwrapCommandTerminalResponse };
@@ -1,4 +1,4 @@
1
- import { BehaviorSubject, EMPTY, NEVER, Observable, ReplaySubject, Subject, animationFrameScheduler, asapScheduler, audit, auditTime, catchError, concat, concatAll, defer, distinctUntilChanged, filter, finalize, firstValueFrom, from, fromEventPattern, lastValueFrom, map, merge, of, share, shareReplay, switchMap, take, takeLast, takeUntil, takeWhile, toArray } from "rxjs";
1
+ import { BehaviorSubject, NEVER, Observable, ReplaySubject, Subject, UnsubscriptionError, animationFrameScheduler, asapScheduler, audit, auditTime, catchError, concatAll, distinctUntilChanged, filter, finalize, firstValueFrom, from, fromEventPattern, lastValueFrom, map, merge, of, shareReplay, switchMap, take, takeLast, takeUntil, takeWhile, toArray } from "rxjs";
2
2
  import { AsyncAction } from "rxjs/internal/scheduler/AsyncAction";
3
3
  import { AsyncScheduler } from "rxjs/internal/scheduler/AsyncScheduler";
4
4
  import { BehaviorSubject as BehaviorSubject$1 } from "rxjs/internal/BehaviorSubject";
@@ -314,7 +314,7 @@ var RxEventReplaySubject = class extends ReplaySubject {
314
314
  }
315
315
  };
316
316
  //#endregion
317
- //#region src/rx/signal.ts
317
+ //#region src/rx/internal/reactive-system/base.ts
318
318
  function watchOptionsToAuditOperator(options) {
319
319
  if (options.schedule === globalThis.queueMicrotask) return auditTime(0, asapScheduler);
320
320
  if (options.schedule === globalThis.requestAnimationFrame && options.cancel === globalThis.cancelAnimationFrame) return auditTime(0, animationFrameScheduler);
@@ -323,9 +323,10 @@ function watchOptionsToAuditOperator(options) {
323
323
  else if (typeof handle === "function") handle();
324
324
  }));
325
325
  }
326
- var RxSignal = class {
326
+ var RxSignal = class RxSignal {
327
327
  static globalEpoch = 0;
328
328
  static currentContext = null;
329
+ static dirtyFrame;
329
330
  valueEqVersion = 0;
330
331
  equals;
331
332
  constructor(options) {
@@ -338,40 +339,125 @@ var RxSignal = class {
338
339
  })));
339
340
  }
340
341
  [SYMBOL_OBSERVABLE]() {
341
- return RxEventStream.fromObservableInput(defer(() => concat(of(this.get()), this.dirtyObservable().pipe(map(() => this.get())))));
342
+ return new RxEventStream((observer) => {
343
+ this.get();
344
+ const subscription = this.dirtyObservable().subscribe({
345
+ next: () => {
346
+ try {
347
+ observer.next(this.get());
348
+ } catch (error) {
349
+ observer.error(error);
350
+ }
351
+ },
352
+ error: (error) => observer.error(error),
353
+ complete: () => observer.complete()
354
+ });
355
+ try {
356
+ observer.next(this.get());
357
+ } catch (error) {
358
+ subscription.unsubscribe();
359
+ observer.error(error);
360
+ }
361
+ return () => subscription.unsubscribe();
362
+ });
363
+ }
364
+ static dispatchDirty(epoch, publish) {
365
+ const previous = RxSignal.dirtyFrame;
366
+ RxSignal.dirtyFrame = { epoch };
367
+ try {
368
+ publish();
369
+ } finally {
370
+ RxSignal.dirtyFrame = previous;
371
+ }
372
+ }
373
+ acceptDirtyEpoch(epoch) {
374
+ const frame = RxSignal.dirtyFrame;
375
+ if (!frame || frame.epoch !== epoch) return true;
376
+ frame.notified ??= /* @__PURE__ */ new Set();
377
+ if (frame.notified.has(this)) return false;
378
+ frame.notified.add(this);
379
+ return true;
380
+ }
381
+ listenDirty(listener) {
382
+ const subscription = this.dirtyObservable().subscribe(listener);
383
+ return () => subscription.unsubscribe();
384
+ }
385
+ static listenToDirty(signal, listener, native) {
386
+ if (native) return signal.listenDirty(listener);
387
+ const subscription = signal.dirtyObservable().subscribe(listener);
388
+ return () => subscription.unsubscribe();
342
389
  }
343
390
  };
391
+ //#endregion
392
+ //#region src/rx/signal.ts
344
393
  var RxStateSignal = class RxStateSignal extends RxSignal {
345
- dirtySubject = new Subject();
394
+ dirtyListeners;
395
+ dirtySnapshot;
396
+ dirty$;
346
397
  value;
398
+ valueSubject;
347
399
  constructor(initialValue, options) {
348
400
  super(options);
349
- this.value = new BehaviorSubject(initialValue);
401
+ this.value = initialValue;
350
402
  }
351
403
  set(input) {
352
- const changed = !this.equals(this.value.getValue(), input);
353
- this.value.next(input);
404
+ const changed = !this.equals(this.value, input);
405
+ this.value = input;
354
406
  if (changed) this.valueEqVersion += 1;
355
407
  RxSignal.globalEpoch += 1;
356
- this.dirtySubject.next({
357
- epoch: RxSignal.globalEpoch,
358
- signal: this
359
- });
408
+ const epoch = RxSignal.globalEpoch;
409
+ this.valueSubject?.next(input);
410
+ const listeners = this.dirtyListeners;
411
+ if (listeners?.size) {
412
+ let snapshot = this.dirtySnapshot;
413
+ if (!snapshot) {
414
+ snapshot = [...listeners];
415
+ this.dirtySnapshot = snapshot;
416
+ }
417
+ RxSignal.dispatchDirty(epoch, () => {
418
+ const event = {
419
+ epoch,
420
+ signal: this
421
+ };
422
+ for (const listener of snapshot) listener.next(event);
423
+ });
424
+ }
360
425
  }
361
426
  static fromInitialValue(initialValue, options) {
362
427
  return new RxStateSignal(initialValue, options);
363
428
  }
364
429
  get() {
365
- const value = this.value.getValue();
430
+ const value = this.value;
366
431
  RxSignal.currentContext?.markDependency(this);
367
432
  return value;
368
433
  }
369
434
  validateForEpoch() {}
370
435
  dirtyObservable() {
371
- return this.dirtySubject.asObservable();
436
+ this.dirty$ ??= new Observable((observer) => this.listenDirty({
437
+ next: (event) => observer.next(event),
438
+ error: (error) => observer.error(error)
439
+ }));
440
+ return this.dirty$;
441
+ }
442
+ listenDirty(listener) {
443
+ this.dirtyListeners ??= /* @__PURE__ */ new Set();
444
+ this.dirtySnapshot = void 0;
445
+ this.dirtyListeners.add(listener);
446
+ return () => {
447
+ this.dirtySnapshot = void 0;
448
+ this.dirtyListeners?.delete(listener);
449
+ };
372
450
  }
373
451
  [SYMBOL_OBSERVABLE]() {
374
- return RxEventStream.fromObservableInput(this.value.asObservable());
452
+ return new RxEventStream((observer) => {
453
+ this.valueSubject ??= new BehaviorSubject(this.value);
454
+ const subject = this.valueSubject;
455
+ const subscription = subject.subscribe(observer);
456
+ return () => {
457
+ subscription.unsubscribe();
458
+ if (!subject.observed && this.valueSubject === subject) this.valueSubject = void 0;
459
+ };
460
+ });
375
461
  }
376
462
  };
377
463
  function haveSameSourceKeys(left, right) {
@@ -389,7 +475,10 @@ var RxComputedSignal = class RxComputedSignal extends RxSignal {
389
475
  computeFn;
390
476
  cacheState = { kind: "empty" };
391
477
  sources = /* @__PURE__ */ new Map();
392
- sourcesSubject = new BehaviorSubject(this.sources);
478
+ dirtyListeners;
479
+ dirtySnapshot;
480
+ dirtyStops;
481
+ dirtyConnection = 0;
393
482
  validatedEpoch = -1;
394
483
  isComputing = false;
395
484
  collectingSources = null;
@@ -433,7 +522,8 @@ var RxComputedSignal = class RxComputedSignal extends RxSignal {
433
522
  RxSignal.currentContext = prevContext;
434
523
  this.isComputing = false;
435
524
  }
436
- const sourcesChanged = !haveSameSourceKeys(this.sources, nextSources);
525
+ const previousSources = this.sources;
526
+ const sourcesChanged = this.dirtyListeners?.size ? !haveSameSourceKeys(previousSources, nextSources) : void 0;
437
527
  let cacheStateChanged;
438
528
  try {
439
529
  cacheStateChanged = !this.cacheStatesEqual(this.cacheState, nextCacheState);
@@ -447,7 +537,11 @@ var RxComputedSignal = class RxComputedSignal extends RxSignal {
447
537
  if (cacheStateChanged) this.valueEqVersion += 1;
448
538
  this.cacheState = nextCacheState;
449
539
  this.sources = nextSources;
450
- if (sourcesChanged) this.sourcesSubject.next(nextSources);
540
+ if (this.dirtyListeners?.size && (sourcesChanged ?? !haveSameSourceKeys(previousSources, nextSources))) try {
541
+ this.syncDirtySources(nextSources);
542
+ } catch (error) {
543
+ this.failDirtySources(error);
544
+ }
451
545
  if (nextCacheState.kind === "error") throw nextCacheState.error;
452
546
  }
453
547
  validateForEpoch(epoch) {
@@ -483,17 +577,104 @@ var RxComputedSignal = class RxComputedSignal extends RxSignal {
483
577
  }
484
578
  }
485
579
  dirtyObservable() {
486
- if (!this.dirty$) this.dirty$ = defer(() => {
487
- this.validateForEpoch(RxSignal.globalEpoch);
488
- return this.sourcesSubject.asObservable().pipe(switchMap((sources) => sources.size === 0 ? EMPTY : merge(...[...sources.keys()].map((source) => source.dirtyObservable())).pipe(distinctUntilChanged((left, right) => left.epoch === right.epoch), map((dirtyDepEvent) => {
489
- return {
490
- epoch: dirtyDepEvent.epoch,
491
- signal: this
492
- };
493
- }))));
494
- }).pipe(share());
580
+ this.dirty$ ??= new Observable((observer) => this.listenDirty({
581
+ next: (event) => observer.next(event),
582
+ error: (error) => observer.error(error)
583
+ }));
495
584
  return this.dirty$;
496
585
  }
586
+ listenDirty(listener) {
587
+ this.validateForEpoch(RxSignal.globalEpoch);
588
+ this.dirtyListeners ??= /* @__PURE__ */ new Set();
589
+ const first = this.dirtyListeners.size === 0;
590
+ this.dirtySnapshot = void 0;
591
+ this.dirtyListeners.add(listener);
592
+ if (first) {
593
+ this.dirtyConnection++;
594
+ try {
595
+ this.syncDirtySources(this.sources);
596
+ } catch (error) {
597
+ this.dirtySnapshot = void 0;
598
+ this.dirtyListeners.delete(listener);
599
+ if (!this.dirtyListeners.size) this.disconnectDirtySources();
600
+ throw error;
601
+ }
602
+ }
603
+ return () => {
604
+ this.dirtySnapshot = void 0;
605
+ this.dirtyListeners?.delete(listener);
606
+ if (!this.dirtyListeners?.size) this.disconnectDirtySources();
607
+ };
608
+ }
609
+ disconnectDirtySources() {
610
+ this.dirtyConnection++;
611
+ const stops = this.dirtyStops;
612
+ this.dirtyStops = void 0;
613
+ let errors;
614
+ for (const stop of stops?.values() ?? []) try {
615
+ stop();
616
+ } catch (error) {
617
+ errors ??= [];
618
+ errors.push(...error instanceof UnsubscriptionError ? error.errors : [error]);
619
+ }
620
+ if (errors) throw new UnsubscriptionError(errors);
621
+ }
622
+ failDirtySources(error) {
623
+ const listeners = [...this.dirtyListeners ?? []];
624
+ this.dirtyListeners?.clear();
625
+ this.dirtySnapshot = void 0;
626
+ let notificationError = error;
627
+ try {
628
+ this.disconnectDirtySources();
629
+ } catch (cleanupError) {
630
+ notificationError = new AggregateError([error, cleanupError], "Dirty propagation and cleanup failed");
631
+ }
632
+ for (const listener of listeners) listener.error(notificationError);
633
+ }
634
+ syncDirtySources(sources) {
635
+ this.dirtyStops ??= /* @__PURE__ */ new Map();
636
+ const stops = this.dirtyStops;
637
+ const connection = this.dirtyConnection;
638
+ for (const [source, stop] of stops) {
639
+ if (!sources.has(source)) {
640
+ stop();
641
+ stops.delete(source);
642
+ }
643
+ if (this.dirtyConnection !== connection) return;
644
+ }
645
+ for (const source of sources.keys()) {
646
+ if (stops.has(source)) continue;
647
+ let active = true;
648
+ const detach = RxSignal.listenToDirty(source, {
649
+ next: (event) => {
650
+ if (!active || this.dirtyConnection !== connection || !this.dirtyListeners?.size || !this.acceptDirtyEpoch(event.epoch)) return;
651
+ const dirtyEvent = {
652
+ epoch: event.epoch,
653
+ signal: this
654
+ };
655
+ let snapshot = this.dirtySnapshot;
656
+ if (!snapshot) {
657
+ snapshot = [...this.dirtyListeners];
658
+ this.dirtySnapshot = snapshot;
659
+ }
660
+ for (const listener of snapshot) listener.next(dirtyEvent);
661
+ },
662
+ error: (error) => {
663
+ if (!active || this.dirtyConnection !== connection) return;
664
+ this.failDirtySources(error);
665
+ }
666
+ }, source.dirtyObservable === RxStateSignal.prototype.dirtyObservable || source.dirtyObservable === RxComputedSignal.prototype.dirtyObservable);
667
+ const stop = () => {
668
+ active = false;
669
+ detach();
670
+ };
671
+ if (!active || this.dirtyConnection !== connection || !this.dirtyListeners?.size) {
672
+ stop();
673
+ return;
674
+ }
675
+ stops.set(source, stop);
676
+ }
677
+ }
497
678
  static computed(fn, options) {
498
679
  return new RxComputedSignal(fn, options);
499
680
  }
@@ -1116,4 +1297,4 @@ function rxResource(options) {
1116
1297
  //#endregion
1117
1298
  export { RxEventSubject as A, withDisposableStack as B, exhaustCommand as C, RxStateSignal as D, RxComputedSignal as E, SYMBOL_DISPOSE as F, ErrorPresentationTone as G, ClientError as H, SimpleDisposableStack as I, UserRecovery as K, StdDisposableStack as L, isInteropObservableTrait as M, SYMBOL_ASYNC_DISPOSE as N, RxEventReplaySubject as O, SYMBOL_DISPOSABLE_STACK as P, createDisposableStack as R, dispatchCommandLocallyToStream as S, unwrapCommandTerminalResponse as T, ClientErrorKind as U, CLIENT_ERROR_SPAN_ATTRIBUTE_PROVIDER_ID as V, ClientErrorSource as W, commandResponseData as _, ResourceSnapshotUpdateKind as a, dispatchCommandByIdToStream as b, whenResourceSnapshotValue as c, ResourceErrorCode as d, CancellationToken as f, CommandResponseType as g, createAsyncSchedulerWithTimestampProvider as h, rxResource as i, SYMBOL_OBSERVABLE as j, RxEventStream as k, ResourceStatus as l, isCancellationTokenTrait as m, mapResource as n, flattenResourceSnapshot as o, createCancellationTokenSource as p, resourceFromSnapshots as r, reduceResourceSnapshot as s, RxResource as t, ResourceError as u, concatCommand as v, switchCommand as w, dispatchCommandLocallyToPromise as x, dispatchCommandByIdToPromise as y, injectDisposableStackFrom as z };
1118
1299
 
1119
- //# sourceMappingURL=rx-DM6Ouv-m.mjs.map
1300
+ //# sourceMappingURL=rx-82t7QNQL.mjs.map