@cratis/arc 22.161.0 → 22.163.0
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/commands/Command.ts +14 -4
- package/commands/for_Command/GeneratedCommand.ts +32 -0
- package/commands/for_Command/when_executing/with_a_failed_submission.ts +40 -0
- package/commands/for_Command/when_executing/with_an_edit_during_submission.ts +33 -0
- package/commands/for_Command/when_executing/with_generated_property_accessors.ts +54 -0
- package/commands/for_Command/when_executing/with_submitted_falsy_values.ts +30 -0
- package/commands/for_Command/when_setting_initial_values_from_current_values.ts +28 -0
- package/dist/cjs/commands/Command.d.ts +1 -0
- package/dist/cjs/commands/Command.d.ts.map +1 -1
- package/dist/cjs/commands/Command.js +13 -4
- package/dist/cjs/commands/Command.js.map +1 -1
- package/dist/cjs/queries/QueryInstanceCache.d.ts +1 -0
- package/dist/cjs/queries/QueryInstanceCache.d.ts.map +1 -1
- package/dist/cjs/queries/QueryInstanceCache.js +6 -2
- package/dist/cjs/queries/QueryInstanceCache.js.map +1 -1
- package/dist/esm/commands/Command.d.ts +1 -0
- package/dist/esm/commands/Command.d.ts.map +1 -1
- package/dist/esm/commands/Command.js +13 -4
- package/dist/esm/commands/Command.js.map +1 -1
- package/dist/esm/commands/for_Command/GeneratedCommand.d.ts +15 -0
- package/dist/esm/commands/for_Command/GeneratedCommand.d.ts.map +1 -0
- package/dist/esm/commands/for_Command/GeneratedCommand.js +24 -0
- package/dist/esm/commands/for_Command/GeneratedCommand.js.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_a_failed_submission.d.ts +2 -0
- package/dist/esm/commands/for_Command/when_executing/with_a_failed_submission.d.ts.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_a_failed_submission.js +34 -0
- package/dist/esm/commands/for_Command/when_executing/with_a_failed_submission.js.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_an_edit_during_submission.d.ts +2 -0
- package/dist/esm/commands/for_Command/when_executing/with_an_edit_during_submission.d.ts.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_an_edit_during_submission.js +26 -0
- package/dist/esm/commands/for_Command/when_executing/with_an_edit_during_submission.js.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_generated_property_accessors.d.ts +2 -0
- package/dist/esm/commands/for_Command/when_executing/with_generated_property_accessors.d.ts.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_generated_property_accessors.js +44 -0
- package/dist/esm/commands/for_Command/when_executing/with_generated_property_accessors.js.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_submitted_falsy_values.d.ts +2 -0
- package/dist/esm/commands/for_Command/when_executing/with_submitted_falsy_values.d.ts.map +1 -0
- package/dist/esm/commands/for_Command/when_executing/with_submitted_falsy_values.js +24 -0
- package/dist/esm/commands/for_Command/when_executing/with_submitted_falsy_values.js.map +1 -0
- package/dist/esm/commands/for_Command/when_setting_initial_values_from_current_values.d.ts +2 -0
- package/dist/esm/commands/for_Command/when_setting_initial_values_from_current_values.d.ts.map +1 -0
- package/dist/esm/commands/for_Command/when_setting_initial_values_from_current_values.js +24 -0
- package/dist/esm/commands/for_Command/when_setting_initial_values_from_current_values.js.map +1 -0
- package/dist/esm/queries/QueryInstanceCache.d.ts +1 -0
- package/dist/esm/queries/QueryInstanceCache.d.ts.map +1 -1
- package/dist/esm/queries/QueryInstanceCache.js +6 -2
- package/dist/esm/queries/QueryInstanceCache.js.map +1 -1
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_changed_metadata.d.ts +2 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_changed_metadata.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_changed_metadata.js +51 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_changed_metadata.js.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_equivalent_metadata.d.ts +2 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_equivalent_metadata.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_equivalent_metadata.js +27 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_equivalent_metadata.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/queries/QueryInstanceCache.ts +17 -4
- package/queries/for_QueryInstanceCache/when_setting_last_result/with_changed_metadata.ts +58 -0
- package/queries/for_QueryInstanceCache/when_setting_last_result/with_equivalent_metadata.ts +39 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryInstanceCache.js","sources":["../../../queries/QueryInstanceCache.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { QueryResultWithState } from './QueryResultWithState.js';\nimport type {\n CacheDiagnostics,\n CacheEntryDiagnostics,\n} from './ObservableQueryDiagnosticsSnapshot.js';\nimport { reconcileQueryData } from './reconcileQueryData.js';\n\n/**\n * Represents a key that uniquely identifies a query instance in the cache, based on the query type name and its serialized arguments.\n */\nexport type QueryCacheKey = string;\n\n/**\n * Callback invoked when the cached result for an entry changes.\n */\nexport type QueryCacheListener<TDataType> = (\n result: QueryResultWithState<TDataType>,\n) => void;\n\n/**\n * Represents a single entry in the {@link QueryInstanceCache}.\n * @template TDataType The type of data returned by the query.\n */\nexport interface QueryCacheEntry<TDataType> {\n /**\n * The cached query instance.\n */\n readonly instance: unknown;\n\n /**\n * The last result received from the query, if any.\n */\n lastResult?: QueryResultWithState<TDataType>;\n\n /**\n * The number of active subscribers holding a reference to this entry.\n */\n subscriberCount: number;\n\n /**\n * Set of listener callbacks that are notified when {@link lastResult} changes.\n */\n readonly listeners: Set<QueryCacheListener<TDataType>>;\n\n /**\n * Cleanup function returned by the first subscriber that starts the query connection.\n * Called when the last subscriber releases the entry.\n */\n teardown?: () => void;\n\n /**\n * Whether an active subscription has been established for this entry.\n */\n subscribed: boolean;\n\n /**\n * Timer handle for deferred cleanup. Allows React StrictMode re-mounts (in any build\n * environment) to cancel the pending teardown so the connection is reused instead of\n * torn down and recreated.\n */\n pendingCleanup?: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Provides a cache for query instances, keyed by query type and serialized arguments.\n *\n * Two callers requesting the same query type with identical arguments receive the same\n * cached instance and immediately see the last known result — without an additional\n * round trip to the server. When the last subscriber releases its reference the entry\n * is evicted.\n */\nexport class QueryInstanceCache {\n private readonly _entries = new Map<QueryCacheKey, QueryCacheEntry<unknown>>();\n private _pendingDispose?: ReturnType<typeof setTimeout>;\n\n /**\n * Initializes a new instance of {@link QueryInstanceCache}.\n * @param retentionMs How long in milliseconds to keep a cache entry alive after the last\n * subscriber releases it before evicting the subscription and cached data. A non-zero\n * value lets users navigate away and back without losing cached data. Defaults to\n * 30 000 ms. Pass 0 for immediate eviction.\n */\n constructor(private readonly _retentionMs: number = 30_000) {}\n\n /**\n * Builds the cache key for a query.\n * @param queryTypeName The stable type name for the query. Use the instance's `queryName`\n * (a hardcoded fully-qualified string in generated proxies) rather than {@link Function.name},\n * which is unstable under minification.\n * @param args Optional arguments supplied to the query.\n * @returns A stable string key.\n */\n buildKey(queryTypeName: string, args?: object): QueryCacheKey {\n if (!args || Object.keys(args).length === 0) {\n return `${queryTypeName}::`;\n }\n\n const sorted = Object.keys(args)\n .sort()\n .reduce<Record<string, unknown>>((accumulator, key) => {\n accumulator[key] = (args as Record<string, unknown>)[key];\n return accumulator;\n }, {});\n\n return `${queryTypeName}::${JSON.stringify(sorted)}`;\n }\n\n /**\n * Returns a cached instance for the given key, or creates a new one using the provided factory.\n * The subscriber count of the entry is incremented.\n * @template TInstance The type of the query instance.\n * @param key The cache key produced by {@link buildKey}.\n * @param factory A zero-argument factory that creates a fresh query instance when one is not yet cached.\n * @returns The cached (or newly created) instance and whether it was newly created.\n */\n getOrCreate<TInstance>(\n key: QueryCacheKey,\n factory: () => TInstance,\n ): { instance: TInstance; isNew: boolean } {\n if (!this._entries.has(key)) {\n const entry: QueryCacheEntry<unknown> = {\n instance: factory(),\n lastResult: undefined,\n subscriberCount: 0,\n listeners: new Set(),\n subscribed: false,\n };\n\n this._entries.set(key, entry);\n return { instance: entry.instance as TInstance, isNew: true };\n }\n\n const entry = this._entries.get(key)!;\n return { instance: entry.instance as TInstance, isNew: false };\n }\n\n /**\n * Increments the active subscriber count for the given key.\n * If a deferred cleanup was pending (from a recent {@link release}),\n * it is cancelled so the existing subscription is reused.\n * Call from `useEffect` setup to pair with {@link release} in the cleanup.\n * @param key The cache key produced by {@link buildKey}.\n */\n acquire(key: QueryCacheKey): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n if (entry.pendingCleanup !== undefined) {\n clearTimeout(entry.pendingCleanup);\n entry.pendingCleanup = undefined;\n }\n\n entry.subscriberCount++;\n }\n }\n\n /**\n * Returns the last cached result for the given key, or `undefined` if no result has been stored yet.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @returns The last {@link QueryResultWithState}, or `undefined`.\n */\n getLastResult<TDataType>(\n key: QueryCacheKey,\n ): QueryResultWithState<TDataType> | undefined {\n return this._entries.get(key)?.lastResult as\n | QueryResultWithState<TDataType>\n | undefined;\n }\n\n /**\n * Stores the most recent result for the given key and notifies all registered listeners.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @param result The result to store.\n */\n setLastResult<TDataType>(\n key: QueryCacheKey,\n result: QueryResultWithState<TDataType>,\n ): void {\n const entry = this._entries.get(key);\n\n if (!entry) {\n return;\n }\n\n const previousResult = entry.lastResult as\n | QueryResultWithState<TDataType>\n | undefined;\n\n // Reconcile the incoming payload against the one already held so items that did not actually\n // change keep their previous references. A full snapshot — which is what the server re-sends\n // whenever a subscription is re-established — otherwise arrives as all-new references and\n // makes every consumer treat every item as changed.\n const reconciled =\n previousResult === undefined\n ? result\n : this.withReconciledData(previousResult, result);\n\n entry.lastResult = reconciled as QueryResultWithState<unknown>;\n\n // Reconciliation returns the previous data reference when nothing changed, so identity is\n // enough to detect it. Data, success, and readiness affect what the user sees; changeSet is\n // ephemeral and does not independently require a notification.\n if (\n previousResult !== undefined &&\n previousResult.isSuccess === reconciled.isSuccess &&\n previousResult.isReady === reconciled.isReady &&\n previousResult.data === reconciled.data\n ) {\n return;\n }\n\n for (const listener of entry.listeners) {\n (listener as QueryCacheListener<TDataType>)(reconciled);\n }\n }\n\n /**\n * Returns the incoming result with its data reconciled against the previous result, or the\n * incoming result unchanged when reconciliation found nothing to carry over.\n * @template TDataType The type of data returned by the query.\n * @param previous The previously held result.\n * @param next The freshly received result.\n * @returns A result whose data preserves references for everything that did not change.\n */\n private withReconciledData<TDataType>(\n previous: QueryResultWithState<TDataType>,\n next: QueryResultWithState<TDataType>,\n ): QueryResultWithState<TDataType> {\n const reconciledData = reconcileQueryData(previous.data, next.data);\n\n if (reconciledData === next.data) {\n return next;\n }\n\n return new QueryResultWithState<TDataType>(\n reconciledData,\n next.paging,\n next.isSuccess,\n next.isAuthorized,\n next.isValid,\n next.validationResults,\n next.hasExceptions,\n next.exceptionMessages,\n next.exceptionStackTrace,\n next.isPerforming,\n next.changeSet,\n next.isReady,\n );\n }\n\n /**\n * Registers a listener that is invoked whenever the cached result for the given key changes.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @param listener The callback to register.\n */\n addListener<TDataType>(\n key: QueryCacheKey,\n listener: QueryCacheListener<TDataType>,\n ): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.listeners.add(listener as QueryCacheListener<unknown>);\n }\n }\n\n /**\n * Removes a previously registered listener.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @param listener The callback to remove.\n */\n removeListener<TDataType>(\n key: QueryCacheKey,\n listener: QueryCacheListener<TDataType>,\n ): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.listeners.delete(listener as QueryCacheListener<unknown>);\n }\n }\n\n /**\n * Stores a teardown function for the given key and marks the entry as subscribed.\n * Called automatically when the last subscriber releases the entry.\n * @param key The cache key produced by {@link buildKey}.\n * @param teardown Cleanup function that disconnects the underlying query subscription.\n */\n setTeardown(key: QueryCacheKey, teardown: () => void): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.teardown = teardown;\n entry.subscribed = true;\n }\n }\n\n /**\n * Returns whether an active subscription exists for the given key.\n * @param key The cache key to check.\n * @returns `true` if a subscription has been established; `false` otherwise.\n */\n isSubscribed(key: QueryCacheKey): boolean {\n return this._entries.get(key)?.subscribed ?? false;\n }\n\n /**\n * Decrements the subscriber count for the given key. When the count reaches zero, both teardown\n * and eviction are deferred by one microtask so that React StrictMode re-mounts — in any build\n * environment — can re-acquire the entry and cancel the cleanup before the timeout fires. This\n * prevents an unnecessary disconnect/reconnect cycle during the synthetic unmount/remount that\n * StrictMode performs.\n * @param key The cache key produced by {@link buildKey}.\n */\n release(key: QueryCacheKey): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.subscriberCount--;\n\n if (entry.subscriberCount <= 0) {\n // Defer both teardown and eviction. React StrictMode re-mounts can cancel by\n // calling acquire() before the timeout fires. A non-zero _retentionMs keeps the\n // entry alive so users navigating back quickly see cached data immediately.\n entry.pendingCleanup = setTimeout(() => {\n const current = this._entries.get(key);\n\n if (current && current.subscriberCount <= 0) {\n current.subscribed = false;\n current.teardown?.();\n current.teardown = undefined;\n current.pendingCleanup = undefined;\n this._entries.delete(key);\n }\n }, this._retentionMs);\n }\n }\n }\n\n /**\n * Returns whether an entry exists for the given key.\n * @param key The cache key to check.\n * @returns `true` if an entry exists; `false` otherwise.\n */\n has(key: QueryCacheKey): boolean {\n return this._entries.has(key);\n }\n\n /**\n * Tears down all active subscriptions and marks every entry as not subscribed,\n * but preserves entries, subscriber counts, and listeners. This allows\n * hooks whose effects re-run afterward to detect that the entry is no longer\n * subscribed and re-establish a fresh connection.\n *\n * Use this when the underlying transport must be replaced (e.g. after an\n * authentication change that requires new WebSocket connections with updated\n * credentials).\n */\n teardownAllSubscriptions(): void {\n for (const [, entry] of this._entries) {\n if (entry.pendingCleanup !== undefined) {\n clearTimeout(entry.pendingCleanup);\n entry.pendingCleanup = undefined;\n }\n\n entry.subscribed = false;\n entry.teardown?.();\n entry.teardown = undefined;\n }\n }\n\n /**\n * Immediately tears down all subscriptions, cancels any pending deferred cleanups,\n * and evicts all entries. Call when the owning component (e.g. the {@link Arc} provider)\n * unmounts permanently so that all query connections are closed synchronously.\n */\n dispose(): void {\n for (const [, entry] of this._entries) {\n if (entry.pendingCleanup !== undefined) {\n clearTimeout(entry.pendingCleanup);\n entry.pendingCleanup = undefined;\n }\n\n entry.subscribed = false;\n entry.teardown?.();\n entry.teardown = undefined;\n }\n\n this._entries.clear();\n }\n\n /**\n * Schedules a deferred {@link dispose} using {@code setTimeout(0)}.\n *\n * This allows React StrictMode re-mounts to call {@link cancelPendingDispose}\n * before the dispose fires, avoiding the destruction of cache entries that child\n * effects are about to re-acquire.\n *\n * If a deferred dispose is already pending, it is replaced.\n */\n deferDispose(): void {\n if (this._pendingDispose !== undefined) {\n clearTimeout(this._pendingDispose);\n }\n\n this._pendingDispose = setTimeout(() => {\n this._pendingDispose = undefined;\n this.dispose();\n }, 0);\n }\n\n /**\n * Cancels a pending deferred dispose scheduled by {@link deferDispose}.\n *\n * Call from the {@code useEffect} setup phase so that a StrictMode re-mount\n * prevents the synthetic unmount's deferred dispose from firing.\n */\n cancelPendingDispose(): void {\n if (this._pendingDispose !== undefined) {\n clearTimeout(this._pendingDispose);\n this._pendingDispose = undefined;\n }\n }\n\n /**\n * Returns a diagnostics snapshot of the current cache state.\n * @returns A {@link CacheDiagnostics} describing all entries.\n */\n getDiagnosticsSnapshot(): CacheDiagnostics {\n const entries: CacheEntryDiagnostics[] = [];\n let totalBytes = 0;\n let unhealthyCount = 0;\n\n for (const [key, entry] of this._entries) {\n const colonIndex = key.indexOf('::');\n const queryName = colonIndex >= 0 ? key.substring(0, colonIndex) : key;\n\n let estimatedBytes = 0;\n try {\n if (entry.lastResult !== undefined) {\n estimatedBytes = JSON.stringify(entry.lastResult).length;\n }\n } catch {\n // Ignore serialization errors\n }\n\n if (entry.subscriberCount > 0 && !entry.subscribed) {\n unhealthyCount++;\n }\n\n totalBytes += estimatedBytes;\n entries.push({\n key,\n queryName,\n subscriberCount: entry.subscriberCount,\n listenerCount: entry.listeners.size,\n subscribed: entry.subscribed,\n hasResult: entry.lastResult !== undefined,\n estimatedBytes,\n });\n }\n\n return {\n healthy: unhealthyCount === 0,\n entryCount: this._entries.size,\n estimatedBytes: totalBytes,\n entries,\n };\n }\n}\n"],"names":["QueryInstanceCache","_entries","Map","_pendingDispose","_retentionMs","buildKey","queryTypeName","args","Object","keys","length","sorted","sort","reduce","accumulator","key","JSON","stringify","getOrCreate","factory","has","entry","instance","lastResult","undefined","subscriberCount","listeners","Set","subscribed","set","isNew","get","acquire","pendingCleanup","clearTimeout","getLastResult","setLastResult","result","previousResult","reconciled","withReconciledData","isSuccess","isReady","data","listener","previous","next","reconciledData","reconcileQueryData","QueryResultWithState","paging","isAuthorized","isValid","validationResults","hasExceptions","exceptionMessages","exceptionStackTrace","isPerforming","changeSet","addListener","add","removeListener","delete","setTeardown","teardown","isSubscribed","release","setTimeout","current","teardownAllSubscriptions","dispose","clear","deferDispose","cancelPendingDispose","getDiagnosticsSnapshot","entries","totalBytes","unhealthyCount","colonIndex","indexOf","queryName","substring","estimatedBytes","push","listenerCount","size","hasResult","healthy","entryCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"QueryInstanceCache.js","sources":["../../../queries/QueryInstanceCache.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { QueryResultWithState } from './QueryResultWithState.js';\nimport type {\n CacheDiagnostics,\n CacheEntryDiagnostics,\n} from './ObservableQueryDiagnosticsSnapshot.js';\nimport { reconcileQueryData } from './reconcileQueryData.js';\nimport { deepEqual } from '../deepEqual.js';\n\n/**\n * Represents a key that uniquely identifies a query instance in the cache, based on the query type name and its serialized arguments.\n */\nexport type QueryCacheKey = string;\n\n/**\n * Callback invoked when the cached result for an entry changes.\n */\nexport type QueryCacheListener<TDataType> = (\n result: QueryResultWithState<TDataType>,\n) => void;\n\n/**\n * Represents a single entry in the {@link QueryInstanceCache}.\n * @template TDataType The type of data returned by the query.\n */\nexport interface QueryCacheEntry<TDataType> {\n /**\n * The cached query instance.\n */\n readonly instance: unknown;\n\n /**\n * The last result received from the query, if any.\n */\n lastResult?: QueryResultWithState<TDataType>;\n\n /**\n * The number of active subscribers holding a reference to this entry.\n */\n subscriberCount: number;\n\n /**\n * Set of listener callbacks that are notified when {@link lastResult} changes.\n */\n readonly listeners: Set<QueryCacheListener<TDataType>>;\n\n /**\n * Cleanup function returned by the first subscriber that starts the query connection.\n * Called when the last subscriber releases the entry.\n */\n teardown?: () => void;\n\n /**\n * Whether an active subscription has been established for this entry.\n */\n subscribed: boolean;\n\n /**\n * Timer handle for deferred cleanup. Allows React StrictMode re-mounts (in any build\n * environment) to cancel the pending teardown so the connection is reused instead of\n * torn down and recreated.\n */\n pendingCleanup?: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Provides a cache for query instances, keyed by query type and serialized arguments.\n *\n * Two callers requesting the same query type with identical arguments receive the same\n * cached instance and immediately see the last known result — without an additional\n * round trip to the server. When the last subscriber releases its reference the entry\n * is evicted.\n */\nexport class QueryInstanceCache {\n private readonly _entries = new Map<QueryCacheKey, QueryCacheEntry<unknown>>();\n private _pendingDispose?: ReturnType<typeof setTimeout>;\n\n /**\n * Initializes a new instance of {@link QueryInstanceCache}.\n * @param retentionMs How long in milliseconds to keep a cache entry alive after the last\n * subscriber releases it before evicting the subscription and cached data. A non-zero\n * value lets users navigate away and back without losing cached data. Defaults to\n * 30 000 ms. Pass 0 for immediate eviction.\n */\n constructor(private readonly _retentionMs: number = 30_000) {}\n\n /**\n * Builds the cache key for a query.\n * @param queryTypeName The stable type name for the query. Use the instance's `queryName`\n * (a hardcoded fully-qualified string in generated proxies) rather than {@link Function.name},\n * which is unstable under minification.\n * @param args Optional arguments supplied to the query.\n * @returns A stable string key.\n */\n buildKey(queryTypeName: string, args?: object): QueryCacheKey {\n if (!args || Object.keys(args).length === 0) {\n return `${queryTypeName}::`;\n }\n\n const sorted = Object.keys(args)\n .sort()\n .reduce<Record<string, unknown>>((accumulator, key) => {\n accumulator[key] = (args as Record<string, unknown>)[key];\n return accumulator;\n }, {});\n\n return `${queryTypeName}::${JSON.stringify(sorted)}`;\n }\n\n /**\n * Returns a cached instance for the given key, or creates a new one using the provided factory.\n * The subscriber count of the entry is incremented.\n * @template TInstance The type of the query instance.\n * @param key The cache key produced by {@link buildKey}.\n * @param factory A zero-argument factory that creates a fresh query instance when one is not yet cached.\n * @returns The cached (or newly created) instance and whether it was newly created.\n */\n getOrCreate<TInstance>(\n key: QueryCacheKey,\n factory: () => TInstance,\n ): { instance: TInstance; isNew: boolean } {\n if (!this._entries.has(key)) {\n const entry: QueryCacheEntry<unknown> = {\n instance: factory(),\n lastResult: undefined,\n subscriberCount: 0,\n listeners: new Set(),\n subscribed: false,\n };\n\n this._entries.set(key, entry);\n return { instance: entry.instance as TInstance, isNew: true };\n }\n\n const entry = this._entries.get(key)!;\n return { instance: entry.instance as TInstance, isNew: false };\n }\n\n /**\n * Increments the active subscriber count for the given key.\n * If a deferred cleanup was pending (from a recent {@link release}),\n * it is cancelled so the existing subscription is reused.\n * Call from `useEffect` setup to pair with {@link release} in the cleanup.\n * @param key The cache key produced by {@link buildKey}.\n */\n acquire(key: QueryCacheKey): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n if (entry.pendingCleanup !== undefined) {\n clearTimeout(entry.pendingCleanup);\n entry.pendingCleanup = undefined;\n }\n\n entry.subscriberCount++;\n }\n }\n\n /**\n * Returns the last cached result for the given key, or `undefined` if no result has been stored yet.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @returns The last {@link QueryResultWithState}, or `undefined`.\n */\n getLastResult<TDataType>(\n key: QueryCacheKey,\n ): QueryResultWithState<TDataType> | undefined {\n return this._entries.get(key)?.lastResult as\n | QueryResultWithState<TDataType>\n | undefined;\n }\n\n /**\n * Stores the most recent result for the given key and notifies all registered listeners.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @param result The result to store.\n */\n setLastResult<TDataType>(\n key: QueryCacheKey,\n result: QueryResultWithState<TDataType>,\n ): void {\n const entry = this._entries.get(key);\n\n if (!entry) {\n return;\n }\n\n const previousResult = entry.lastResult as\n | QueryResultWithState<TDataType>\n | undefined;\n\n // Reconcile the incoming payload against the one already held so items that did not actually\n // change keep their previous references. A full snapshot — which is what the server re-sends\n // whenever a subscription is re-established — otherwise arrives as all-new references and\n // makes every consumer treat every item as changed.\n const reconciled =\n previousResult === undefined\n ? result\n : this.withReconciledData(previousResult, result);\n\n entry.lastResult = reconciled as QueryResultWithState<unknown>;\n\n // Reconciliation returns the previous data reference when nothing changed, so identity is\n // enough to detect it. Data and result metadata affect what the user sees; changeSet is\n // ephemeral and does not independently require a notification.\n if (\n previousResult !== undefined &&\n previousResult.data === reconciled.data &&\n this.hasEquivalentMetadata(previousResult, reconciled)\n ) {\n return;\n }\n\n for (const listener of entry.listeners) {\n (listener as QueryCacheListener<TDataType>)(reconciled);\n }\n }\n\n /**\n * Returns the incoming result with its data reconciled against the previous result, or the\n * incoming result unchanged when reconciliation found nothing to carry over.\n * @template TDataType The type of data returned by the query.\n * @param previous The previously held result.\n * @param next The freshly received result.\n * @returns A result whose data preserves references for everything that did not change.\n */\n private withReconciledData<TDataType>(\n previous: QueryResultWithState<TDataType>,\n next: QueryResultWithState<TDataType>,\n ): QueryResultWithState<TDataType> {\n const reconciledData = reconcileQueryData(previous.data, next.data);\n\n if (reconciledData === next.data) {\n return next;\n }\n\n return new QueryResultWithState<TDataType>(\n reconciledData,\n next.paging,\n next.isSuccess,\n next.isAuthorized,\n next.isValid,\n next.validationResults,\n next.hasExceptions,\n next.exceptionMessages,\n next.exceptionStackTrace,\n next.isPerforming,\n next.changeSet,\n next.isReady,\n );\n }\n\n private hasEquivalentMetadata<TDataType>(result: QueryResultWithState<TDataType>, previous: QueryResultWithState<TDataType>): boolean {\n return result.isPerforming === previous.isPerforming\n && result.isSuccess === previous.isSuccess\n && result.isReady === previous.isReady\n && result.isAuthorized === previous.isAuthorized\n && result.isValid === previous.isValid\n && result.hasExceptions === previous.hasExceptions\n && result.exceptionStackTrace === previous.exceptionStackTrace\n && deepEqual(result.paging, previous.paging)\n && deepEqual(result.exceptionMessages, previous.exceptionMessages)\n && deepEqual(result.validationResults, previous.validationResults);\n }\n\n /**\n * Registers a listener that is invoked whenever the cached result for the given key changes.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @param listener The callback to register.\n */\n addListener<TDataType>(\n key: QueryCacheKey,\n listener: QueryCacheListener<TDataType>,\n ): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.listeners.add(listener as QueryCacheListener<unknown>);\n }\n }\n\n /**\n * Removes a previously registered listener.\n * @template TDataType The type of data returned by the query.\n * @param key The cache key produced by {@link buildKey}.\n * @param listener The callback to remove.\n */\n removeListener<TDataType>(\n key: QueryCacheKey,\n listener: QueryCacheListener<TDataType>,\n ): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.listeners.delete(listener as QueryCacheListener<unknown>);\n }\n }\n\n /**\n * Stores a teardown function for the given key and marks the entry as subscribed.\n * Called automatically when the last subscriber releases the entry.\n * @param key The cache key produced by {@link buildKey}.\n * @param teardown Cleanup function that disconnects the underlying query subscription.\n */\n setTeardown(key: QueryCacheKey, teardown: () => void): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.teardown = teardown;\n entry.subscribed = true;\n }\n }\n\n /**\n * Returns whether an active subscription exists for the given key.\n * @param key The cache key to check.\n * @returns `true` if a subscription has been established; `false` otherwise.\n */\n isSubscribed(key: QueryCacheKey): boolean {\n return this._entries.get(key)?.subscribed ?? false;\n }\n\n /**\n * Decrements the subscriber count for the given key. When the count reaches zero, both teardown\n * and eviction are deferred by one microtask so that React StrictMode re-mounts — in any build\n * environment — can re-acquire the entry and cancel the cleanup before the timeout fires. This\n * prevents an unnecessary disconnect/reconnect cycle during the synthetic unmount/remount that\n * StrictMode performs.\n * @param key The cache key produced by {@link buildKey}.\n */\n release(key: QueryCacheKey): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.subscriberCount--;\n\n if (entry.subscriberCount <= 0) {\n // Defer both teardown and eviction. React StrictMode re-mounts can cancel by\n // calling acquire() before the timeout fires. A non-zero _retentionMs keeps the\n // entry alive so users navigating back quickly see cached data immediately.\n entry.pendingCleanup = setTimeout(() => {\n const current = this._entries.get(key);\n\n if (current && current.subscriberCount <= 0) {\n current.subscribed = false;\n current.teardown?.();\n current.teardown = undefined;\n current.pendingCleanup = undefined;\n this._entries.delete(key);\n }\n }, this._retentionMs);\n }\n }\n }\n\n /**\n * Returns whether an entry exists for the given key.\n * @param key The cache key to check.\n * @returns `true` if an entry exists; `false` otherwise.\n */\n has(key: QueryCacheKey): boolean {\n return this._entries.has(key);\n }\n\n /**\n * Tears down all active subscriptions and marks every entry as not subscribed,\n * but preserves entries, subscriber counts, and listeners. This allows\n * hooks whose effects re-run afterward to detect that the entry is no longer\n * subscribed and re-establish a fresh connection.\n *\n * Use this when the underlying transport must be replaced (e.g. after an\n * authentication change that requires new WebSocket connections with updated\n * credentials).\n */\n teardownAllSubscriptions(): void {\n for (const [, entry] of this._entries) {\n if (entry.pendingCleanup !== undefined) {\n clearTimeout(entry.pendingCleanup);\n entry.pendingCleanup = undefined;\n }\n\n entry.subscribed = false;\n entry.teardown?.();\n entry.teardown = undefined;\n }\n }\n\n /**\n * Immediately tears down all subscriptions, cancels any pending deferred cleanups,\n * and evicts all entries. Call when the owning component (e.g. the {@link Arc} provider)\n * unmounts permanently so that all query connections are closed synchronously.\n */\n dispose(): void {\n for (const [, entry] of this._entries) {\n if (entry.pendingCleanup !== undefined) {\n clearTimeout(entry.pendingCleanup);\n entry.pendingCleanup = undefined;\n }\n\n entry.subscribed = false;\n entry.teardown?.();\n entry.teardown = undefined;\n }\n\n this._entries.clear();\n }\n\n /**\n * Schedules a deferred {@link dispose} using {@code setTimeout(0)}.\n *\n * This allows React StrictMode re-mounts to call {@link cancelPendingDispose}\n * before the dispose fires, avoiding the destruction of cache entries that child\n * effects are about to re-acquire.\n *\n * If a deferred dispose is already pending, it is replaced.\n */\n deferDispose(): void {\n if (this._pendingDispose !== undefined) {\n clearTimeout(this._pendingDispose);\n }\n\n this._pendingDispose = setTimeout(() => {\n this._pendingDispose = undefined;\n this.dispose();\n }, 0);\n }\n\n /**\n * Cancels a pending deferred dispose scheduled by {@link deferDispose}.\n *\n * Call from the {@code useEffect} setup phase so that a StrictMode re-mount\n * prevents the synthetic unmount's deferred dispose from firing.\n */\n cancelPendingDispose(): void {\n if (this._pendingDispose !== undefined) {\n clearTimeout(this._pendingDispose);\n this._pendingDispose = undefined;\n }\n }\n\n /**\n * Returns a diagnostics snapshot of the current cache state.\n * @returns A {@link CacheDiagnostics} describing all entries.\n */\n getDiagnosticsSnapshot(): CacheDiagnostics {\n const entries: CacheEntryDiagnostics[] = [];\n let totalBytes = 0;\n let unhealthyCount = 0;\n\n for (const [key, entry] of this._entries) {\n const colonIndex = key.indexOf('::');\n const queryName = colonIndex >= 0 ? key.substring(0, colonIndex) : key;\n\n let estimatedBytes = 0;\n try {\n if (entry.lastResult !== undefined) {\n estimatedBytes = JSON.stringify(entry.lastResult).length;\n }\n } catch {\n // Ignore serialization errors\n }\n\n if (entry.subscriberCount > 0 && !entry.subscribed) {\n unhealthyCount++;\n }\n\n totalBytes += estimatedBytes;\n entries.push({\n key,\n queryName,\n subscriberCount: entry.subscriberCount,\n listenerCount: entry.listeners.size,\n subscribed: entry.subscribed,\n hasResult: entry.lastResult !== undefined,\n estimatedBytes,\n });\n }\n\n return {\n healthy: unhealthyCount === 0,\n entryCount: this._entries.size,\n estimatedBytes: totalBytes,\n entries,\n };\n }\n}\n"],"names":["QueryInstanceCache","_entries","Map","_pendingDispose","_retentionMs","buildKey","queryTypeName","args","Object","keys","length","sorted","sort","reduce","accumulator","key","JSON","stringify","getOrCreate","factory","has","entry","instance","lastResult","undefined","subscriberCount","listeners","Set","subscribed","set","isNew","get","acquire","pendingCleanup","clearTimeout","getLastResult","setLastResult","result","previousResult","reconciled","withReconciledData","data","hasEquivalentMetadata","listener","previous","next","reconciledData","reconcileQueryData","QueryResultWithState","paging","isSuccess","isAuthorized","isValid","validationResults","hasExceptions","exceptionMessages","exceptionStackTrace","isPerforming","changeSet","isReady","deepEqual","addListener","add","removeListener","delete","setTeardown","teardown","isSubscribed","release","setTimeout","current","teardownAllSubscriptions","dispose","clear","deferDispose","cancelPendingDispose","getDiagnosticsSnapshot","entries","totalBytes","unhealthyCount","colonIndex","indexOf","queryName","substring","estimatedBytes","push","listenerCount","size","hasResult","healthy","entryCount"],"mappings":";;;;;;AAAA;AACA;AAkEA;;;;;;;AAOC,IACM,MAAMA,kBAAAA,CAAAA;;AACQC,IAAAA,QAAAA,GAAW,IAAIC,GAAAA,EAAAA;IACxBC,eAAAA;AAER;;;;;;AAMC,QACD,WAAA,CAA6BC,YAAAA,GAAuB,MAAM,CAAE;aAA/BA,YAAAA,GAAAA,YAAAA;AAAgC,IAAA;AAE7D;;;;;;;AAOC,QACDC,QAAAA,CAASC,aAAqB,EAAEC,IAAa,EAAiB;QAC1D,IAAI,CAACA,QAAQC,MAAAA,CAAOC,IAAI,CAACF,IAAAA,CAAAA,CAAMG,MAAM,KAAK,CAAA,EAAG;YACzC,OAAO,CAAA,EAAGJ,aAAAA,CAAc,EAAE,CAAC;AAC/B,QAAA;QAEA,MAAMK,MAAAA,GAASH,MAAAA,CAAOC,IAAI,CAACF,IAAAA,CAAAA,CACtBK,IAAI,EAAA,CACJC,MAAM,CAA0B,CAACC,WAAAA,EAAaC,GAAAA,GAAAA;AAC3CD,YAAAA,WAAW,CAACC,GAAAA,CAAI,GAAG,IAAiC,CAACA,GAAAA,CAAI;YACzD,OAAOD,WAAAA;AACX,QAAA,CAAA,EAAG,EAAC,CAAA;AAER,QAAA,OAAO,GAAGR,aAAAA,CAAc,EAAE,EAAEU,IAAAA,CAAKC,SAAS,CAACN,MAAAA,CAAAA,CAAAA,CAAS;AACxD,IAAA;AAEA;;;;;;;AAOC,QACDO,WAAAA,CACIH,GAAkB,EAClBI,OAAwB,EACe;AACvC,QAAA,IAAI,CAAC,IAAI,CAAClB,QAAQ,CAACmB,GAAG,CAACL,GAAAA,CAAAA,EAAM;AACzB,YAAA,MAAMM,KAAAA,GAAkC;gBACpCC,QAAAA,EAAUH,OAAAA,EAAAA;gBACVI,UAAAA,EAAYC,SAAAA;gBACZC,eAAAA,EAAiB,CAAA;AACjBC,gBAAAA,SAAAA,EAAW,IAAIC,GAAAA,EAAAA;gBACfC,UAAAA,EAAY;AAChB,aAAA;AAEA,YAAA,IAAI,CAAC3B,QAAQ,CAAC4B,GAAG,CAACd,GAAAA,EAAKM,KAAAA,CAAAA;YACvB,OAAO;AAAEC,gBAAAA,QAAAA,EAAUD,MAAMC,QAAQ;gBAAeQ,KAAAA,EAAO;AAAK,aAAA;AAChE,QAAA;AAEA,QAAA,MAAMT,QAAQ,IAAI,CAACpB,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;QAChC,OAAO;AAAEO,YAAAA,QAAAA,EAAUD,MAAMC,QAAQ;YAAeQ,KAAAA,EAAO;AAAM,SAAA;AACjE,IAAA;AAEA;;;;;;QAOAE,OAAAA,CAAQjB,GAAkB,EAAQ;AAC9B,QAAA,MAAMM,QAAQ,IAAI,CAACpB,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;AAEhC,QAAA,IAAIM,KAAAA,EAAO;YACP,IAAIA,KAAAA,CAAMY,cAAc,KAAKT,SAAAA,EAAW;AACpCU,gBAAAA,YAAAA,CAAab,MAAMY,cAAc,CAAA;AACjCZ,gBAAAA,KAAAA,CAAMY,cAAc,GAAGT,SAAAA;AAC3B,YAAA;AAEAH,YAAAA,KAAAA,CAAMI,eAAe,EAAA;AACzB,QAAA;AACJ,IAAA;AAEA;;;;;QAMAU,aAAAA,CACIpB,GAAkB,EACyB;AAC3C,QAAA,OAAO,IAAI,CAACd,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA,EAAMQ,UAAAA;AAGnC,IAAA;AAEA;;;;;AAKC,QACDa,aAAAA,CACIrB,GAAkB,EAClBsB,MAAuC,EACnC;AACJ,QAAA,MAAMhB,QAAQ,IAAI,CAACpB,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;AAEhC,QAAA,IAAI,CAACM,KAAAA,EAAO;AACR,YAAA;AACJ,QAAA;QAEA,MAAMiB,cAAAA,GAAiBjB,MAAME,UAAU;;;;;QAQvC,MAAMgB,UAAAA,GACFD,mBAAmBd,SAAAA,GACba,MAAAA,GACA,IAAI,CAACG,kBAAkB,CAACF,cAAAA,EAAgBD,MAAAA,CAAAA;AAElDhB,QAAAA,KAAAA,CAAME,UAAU,GAAGgB,UAAAA;;;;AAKnB,QAAA,IACID,cAAAA,KAAmBd,SAAAA,IACnBc,cAAAA,CAAeG,IAAI,KAAKF,UAAAA,CAAWE,IAAI,IACvC,IAAI,CAACC,qBAAqB,CAACJ,gBAAgBC,UAAAA,CAAAA,EAC7C;AACE,YAAA;AACJ,QAAA;AAEA,QAAA,KAAK,MAAMI,QAAAA,IAAYtB,KAAAA,CAAMK,SAAS,CAAE;YACnCiB,QAAAA,CAA2CJ,UAAAA,CAAAA;AAChD,QAAA;AACJ,IAAA;AAEA;;;;;;;AAOC,QACD,kBAAQC,CACJI,QAAyC,EACzCC,IAAqC,EACN;AAC/B,QAAA,MAAMC,iBAAiBC,qCAAAA,CAAmBH,QAAAA,CAASH,IAAI,EAAEI,KAAKJ,IAAI,CAAA;QAElE,IAAIK,cAAAA,KAAmBD,IAAAA,CAAKJ,IAAI,EAAE;YAC9B,OAAOI,IAAAA;AACX,QAAA;AAEA,QAAA,OAAO,IAAIG,yCAAAA,CACPF,cAAAA,EACAD,IAAAA,CAAKI,MAAM,EACXJ,IAAAA,CAAKK,SAAS,EACdL,KAAKM,YAAY,EACjBN,IAAAA,CAAKO,OAAO,EACZP,IAAAA,CAAKQ,iBAAiB,EACtBR,IAAAA,CAAKS,aAAa,EAClBT,IAAAA,CAAKU,iBAAiB,EACtBV,IAAAA,CAAKW,mBAAmB,EACxBX,IAAAA,CAAKY,YAAY,EACjBZ,IAAAA,CAAKa,SAAS,EACdb,KAAKc,OAAO,CAAA;AAEpB,IAAA;IAEQjB,qBAAAA,CAAiCL,MAAuC,EAAEO,QAAyC,EAAW;AAClI,QAAA,OAAOP,MAAAA,CAAOoB,YAAY,KAAKb,QAAAA,CAASa,YAAY,IAC7CpB,MAAAA,CAAOa,SAAS,KAAKN,QAAAA,CAASM,SAAS,IACvCb,MAAAA,CAAOsB,OAAO,KAAKf,QAAAA,CAASe,OAAO,IACnCtB,MAAAA,CAAOc,YAAY,KAAKP,QAAAA,CAASO,YAAY,IAC7Cd,MAAAA,CAAOe,OAAO,KAAKR,QAAAA,CAASQ,OAAO,IACnCf,MAAAA,CAAOiB,aAAa,KAAKV,QAAAA,CAASU,aAAa,IAC/CjB,MAAAA,CAAOmB,mBAAmB,KAAKZ,QAAAA,CAASY,mBAAmB,IAC3DI,mBAAAA,CAAUvB,MAAAA,CAAOY,MAAM,EAAEL,QAAAA,CAASK,MAAM,CAAA,IACxCW,mBAAAA,CAAUvB,MAAAA,CAAOkB,iBAAiB,EAAEX,QAAAA,CAASW,iBAAiB,CAAA,IAC9DK,mBAAAA,CAAUvB,MAAAA,CAAOgB,iBAAiB,EAAET,SAASS,iBAAiB,CAAA;AACzE,IAAA;AAEA;;;;;AAKC,QACDQ,WAAAA,CACI9C,GAAkB,EAClB4B,QAAuC,EACnC;AACJ,QAAA,MAAMtB,QAAQ,IAAI,CAACpB,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;AAEhC,QAAA,IAAIM,KAAAA,EAAO;YACPA,KAAAA,CAAMK,SAAS,CAACoC,GAAG,CAACnB,QAAAA,CAAAA;AACxB,QAAA;AACJ,IAAA;AAEA;;;;;AAKC,QACDoB,cAAAA,CACIhD,GAAkB,EAClB4B,QAAuC,EACnC;AACJ,QAAA,MAAMtB,QAAQ,IAAI,CAACpB,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;AAEhC,QAAA,IAAIM,KAAAA,EAAO;YACPA,KAAAA,CAAMK,SAAS,CAACsC,MAAM,CAACrB,QAAAA,CAAAA;AAC3B,QAAA;AACJ,IAAA;AAEA;;;;;AAKC,QACDsB,WAAAA,CAAYlD,GAAkB,EAAEmD,QAAoB,EAAQ;AACxD,QAAA,MAAM7C,QAAQ,IAAI,CAACpB,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;AAEhC,QAAA,IAAIM,KAAAA,EAAO;AACPA,YAAAA,KAAAA,CAAM6C,QAAQ,GAAGA,QAAAA;AACjB7C,YAAAA,KAAAA,CAAMO,UAAU,GAAG,IAAA;AACvB,QAAA;AACJ,IAAA;AAEA;;;;QAKAuC,YAAAA,CAAapD,GAAkB,EAAW;AACtC,QAAA,OAAO,IAAI,CAACd,QAAQ,CAAC8B,GAAG,CAAChB,MAAMa,UAAAA,IAAc,KAAA;AACjD,IAAA;AAEA;;;;;;;QAQAwC,OAAAA,CAAQrD,GAAkB,EAAQ;AAC9B,QAAA,MAAMM,QAAQ,IAAI,CAACpB,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;AAEhC,QAAA,IAAIM,KAAAA,EAAO;AACPA,YAAAA,KAAAA,CAAMI,eAAe,EAAA;YAErB,IAAIJ,KAAAA,CAAMI,eAAe,IAAI,CAAA,EAAG;;;;gBAI5BJ,KAAAA,CAAMY,cAAc,GAAGoC,UAAAA,CAAW,IAAA;AAC9B,oBAAA,MAAMC,UAAU,IAAI,CAACrE,QAAQ,CAAC8B,GAAG,CAAChB,GAAAA,CAAAA;AAElC,oBAAA,IAAIuD,OAAAA,IAAWA,OAAAA,CAAQ7C,eAAe,IAAI,CAAA,EAAG;AACzC6C,wBAAAA,OAAAA,CAAQ1C,UAAU,GAAG,KAAA;AACrB0C,wBAAAA,OAAAA,CAAQJ,QAAQ,IAAA;AAChBI,wBAAAA,OAAAA,CAAQJ,QAAQ,GAAG1C,SAAAA;AACnB8C,wBAAAA,OAAAA,CAAQrC,cAAc,GAAGT,SAAAA;AACzB,wBAAA,IAAI,CAACvB,QAAQ,CAAC+D,MAAM,CAACjD,GAAAA,CAAAA;AACzB,oBAAA;gBACJ,CAAA,EAAG,IAAI,CAACX,YAAY,CAAA;AACxB,YAAA;AACJ,QAAA;AACJ,IAAA;AAEA;;;;QAKAgB,GAAAA,CAAIL,GAAkB,EAAW;AAC7B,QAAA,OAAO,IAAI,CAACd,QAAQ,CAACmB,GAAG,CAACL,GAAAA,CAAAA;AAC7B,IAAA;AAEA;;;;;;;;;AASC,QACDwD,wBAAAA,GAAiC;AAC7B,QAAA,KAAK,MAAM,GAAGlD,KAAAA,CAAM,IAAI,IAAI,CAACpB,QAAQ,CAAE;YACnC,IAAIoB,KAAAA,CAAMY,cAAc,KAAKT,SAAAA,EAAW;AACpCU,gBAAAA,YAAAA,CAAab,MAAMY,cAAc,CAAA;AACjCZ,gBAAAA,KAAAA,CAAMY,cAAc,GAAGT,SAAAA;AAC3B,YAAA;AAEAH,YAAAA,KAAAA,CAAMO,UAAU,GAAG,KAAA;AACnBP,YAAAA,KAAAA,CAAM6C,QAAQ,IAAA;AACd7C,YAAAA,KAAAA,CAAM6C,QAAQ,GAAG1C,SAAAA;AACrB,QAAA;AACJ,IAAA;AAEA;;;;AAIC,QACDgD,OAAAA,GAAgB;AACZ,QAAA,KAAK,MAAM,GAAGnD,KAAAA,CAAM,IAAI,IAAI,CAACpB,QAAQ,CAAE;YACnC,IAAIoB,KAAAA,CAAMY,cAAc,KAAKT,SAAAA,EAAW;AACpCU,gBAAAA,YAAAA,CAAab,MAAMY,cAAc,CAAA;AACjCZ,gBAAAA,KAAAA,CAAMY,cAAc,GAAGT,SAAAA;AAC3B,YAAA;AAEAH,YAAAA,KAAAA,CAAMO,UAAU,GAAG,KAAA;AACnBP,YAAAA,KAAAA,CAAM6C,QAAQ,IAAA;AACd7C,YAAAA,KAAAA,CAAM6C,QAAQ,GAAG1C,SAAAA;AACrB,QAAA;QAEA,IAAI,CAACvB,QAAQ,CAACwE,KAAK,EAAA;AACvB,IAAA;AAEA;;;;;;;;AAQC,QACDC,YAAAA,GAAqB;AACjB,QAAA,IAAI,IAAI,CAACvE,eAAe,KAAKqB,SAAAA,EAAW;YACpCU,YAAAA,CAAa,IAAI,CAAC/B,eAAe,CAAA;AACrC,QAAA;QAEA,IAAI,CAACA,eAAe,GAAGkE,UAAAA,CAAW,IAAA;YAC9B,IAAI,CAAClE,eAAe,GAAGqB,SAAAA;AACvB,YAAA,IAAI,CAACgD,OAAO,EAAA;QAChB,CAAA,EAAG,CAAA,CAAA;AACP,IAAA;AAEA;;;;;AAKC,QACDG,oBAAAA,GAA6B;AACzB,QAAA,IAAI,IAAI,CAACxE,eAAe,KAAKqB,SAAAA,EAAW;YACpCU,YAAAA,CAAa,IAAI,CAAC/B,eAAe,CAAA;YACjC,IAAI,CAACA,eAAe,GAAGqB,SAAAA;AAC3B,QAAA;AACJ,IAAA;AAEA;;;AAGC,QACDoD,sBAAAA,GAA2C;AACvC,QAAA,MAAMC,UAAmC,EAAE;AAC3C,QAAA,IAAIC,UAAAA,GAAa,CAAA;AACjB,QAAA,IAAIC,cAAAA,GAAiB,CAAA;QAErB,KAAK,MAAM,CAAChE,GAAAA,EAAKM,KAAAA,CAAM,IAAI,IAAI,CAACpB,QAAQ,CAAE;YACtC,MAAM+E,UAAAA,GAAajE,GAAAA,CAAIkE,OAAO,CAAC,IAAA,CAAA;AAC/B,YAAA,MAAMC,YAAYF,UAAAA,IAAc,CAAA,GAAIjE,IAAIoE,SAAS,CAAC,GAAGH,UAAAA,CAAAA,GAAcjE,GAAAA;AAEnE,YAAA,IAAIqE,cAAAA,GAAiB,CAAA;YACrB,IAAI;gBACA,IAAI/D,KAAAA,CAAME,UAAU,KAAKC,SAAAA,EAAW;AAChC4D,oBAAAA,cAAAA,GAAiBpE,KAAKC,SAAS,CAACI,KAAAA,CAAME,UAAU,EAAEb,MAAM;AAC5D,gBAAA;AACJ,YAAA,CAAA,CAAE,OAAM;;AAER,YAAA;AAEA,YAAA,IAAIW,MAAMI,eAAe,GAAG,KAAK,CAACJ,KAAAA,CAAMO,UAAU,EAAE;AAChDmD,gBAAAA,cAAAA,EAAAA;AACJ,YAAA;YAEAD,UAAAA,IAAcM,cAAAA;AACdP,YAAAA,OAAAA,CAAQQ,IAAI,CAAC;AACTtE,gBAAAA,GAAAA;AACAmE,gBAAAA,SAAAA;AACAzD,gBAAAA,eAAAA,EAAiBJ,MAAMI,eAAe;gBACtC6D,aAAAA,EAAejE,KAAAA,CAAMK,SAAS,CAAC6D,IAAI;AACnC3D,gBAAAA,UAAAA,EAAYP,MAAMO,UAAU;gBAC5B4D,SAAAA,EAAWnE,KAAAA,CAAME,UAAU,KAAKC,SAAAA;AAChC4D,gBAAAA;AACJ,aAAA,CAAA;AACJ,QAAA;QAEA,OAAO;AACHK,YAAAA,OAAAA,EAASV,cAAAA,KAAmB,CAAA;AAC5BW,YAAAA,UAAAA,EAAY,IAAI,CAACzF,QAAQ,CAACsF,IAAI;YAC9BH,cAAAA,EAAgBN,UAAAA;AAChBD,YAAAA;AACJ,SAAA;AACJ,IAAA;AACJ;;"}
|
|
@@ -39,6 +39,7 @@ export declare abstract class Command<TCommandContent = object, TCommandResponse
|
|
|
39
39
|
clear(): void;
|
|
40
40
|
setInitialValues(values: TCommandContent): void;
|
|
41
41
|
setInitialValuesFromCurrentValues(): void;
|
|
42
|
+
private captureCurrentValues;
|
|
42
43
|
revertChanges(): void;
|
|
43
44
|
get hasChanges(): boolean;
|
|
44
45
|
propertyChanged(property: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Command.d.ts","sourceRoot":"","sources":["../../../commands/Command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAkB,MAAM,sBAAsB,CAAC;AAInE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAcrF,8BAAsB,OAAO,CAAC,eAAe,GAAG,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAAE,YAAW,QAAQ,CAAC,eAAe,EAAE,gBAAgB,CAAC;IA6BzH,QAAQ,CAAC,aAAa,EAAE,WAAW;IAAW,QAAQ,CAAC,yBAAyB,EAAE,OAAO;IAzBrG,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAuB;IAEnE,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAiB;IAC7C,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEhC,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE5C,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAM;IAE9B,QAAQ,CAAC,yBAAyB,CAAC,EAAE,wBAAwB,CAAC;IAC9D,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC5D,QAAQ,KAAK,iBAAiB,IAAI,MAAM,EAAE,CAAC;IAE3C,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAkB;IAOpC,YAAqB,aAAa,EAAE,WAAW,YAAS,EAAW,yBAAyB,EAAE,OAAO,EAKpG;IAGD,eAAe,CAAC,YAAY,EAAE,MAAM,QAEnC;IAGD,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAExC;IAGD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9B;IAGD,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAErD;IAGK,OAAO,CAAC,eAAe,CAAC,EAAE,wBAAwB,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"Command.d.ts","sourceRoot":"","sources":["../../../commands/Command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAkB,MAAM,sBAAsB,CAAC;AAInE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAcrF,8BAAsB,OAAO,CAAC,eAAe,GAAG,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAAE,YAAW,QAAQ,CAAC,eAAe,EAAE,gBAAgB,CAAC;IA6BzH,QAAQ,CAAC,aAAa,EAAE,WAAW;IAAW,QAAQ,CAAC,yBAAyB,EAAE,OAAO;IAzBrG,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAuB;IAEnE,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAiB;IAC7C,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEhC,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE5C,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAM;IAE9B,QAAQ,CAAC,yBAAyB,CAAC,EAAE,wBAAwB,CAAC;IAC9D,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC5D,QAAQ,KAAK,iBAAiB,IAAI,MAAM,EAAE,CAAC;IAE3C,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAkB;IAOpC,YAAqB,aAAa,EAAE,WAAW,YAAS,EAAW,yBAAyB,EAAE,OAAO,EAKpG;IAGD,eAAe,CAAC,YAAY,EAAE,MAAM,QAEnC;IAGD,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAExC;IAGD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9B;IAGD,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAErD;IAGK,OAAO,CAAC,eAAe,CAAC,EAAE,wBAAwB,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CA4B5H;IAGK,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CA2BzD;IAGD,kBAAkB,IAAI,aAAa,CAAC,gBAAgB,CAAC,CAwBpD;IAED,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,0BAA0B;IAoBlC,OAAO,CAAC,iCAAiC;IAczC,OAAO,CAAC,YAAY;YAuBN,cAAc;IA+B5B,KAAK,IAAI,IAAI,CAOZ;IAGD,gBAAgB,CAAC,MAAM,EAAE,eAAe,QASvC;IAGD,iCAAiC,SAGhC;IAED,OAAO,CAAC,oBAAoB;IAY5B,aAAa,IAAI,IAAI,CAKpB;IAGD,IAAI,UAAU,YAEb;IAGD,eAAe,CAAC,QAAQ,EAAE,MAAM,QAY/B;IAGD,iBAAiB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,QAK3D;IAED,OAAO,CAAC,gBAAgB;CAM3B"}
|
|
@@ -72,8 +72,12 @@ import { ValidationResultReasonDetail } from '../validation/ValidationResultReas
|
|
|
72
72
|
const { route } = UrlHelpers.replaceRouteParameters(this.route, payload);
|
|
73
73
|
actualRoute = route;
|
|
74
74
|
}
|
|
75
|
+
const submittedValues = this.captureCurrentValues();
|
|
75
76
|
const result = await this.performRequest(actualRoute, 'Command not found at route', 'Error during server call', allowedSeverity, ignoreWarnings);
|
|
76
|
-
|
|
77
|
+
if (result.isSuccess) {
|
|
78
|
+
this._initialValues = submittedValues;
|
|
79
|
+
this.updateHasChanges();
|
|
80
|
+
}
|
|
77
81
|
return result;
|
|
78
82
|
}
|
|
79
83
|
/** @inheritdoc */ async validate() {
|
|
@@ -226,13 +230,18 @@ import { ValidationResultReasonDetail } from '../validation/ValidationResultReas
|
|
|
226
230
|
this.updateHasChanges();
|
|
227
231
|
}
|
|
228
232
|
/** @inheritdoc */ setInitialValuesFromCurrentValues() {
|
|
233
|
+
this._initialValues = this.captureCurrentValues();
|
|
234
|
+
this.updateHasChanges();
|
|
235
|
+
}
|
|
236
|
+
captureCurrentValues() {
|
|
237
|
+
const values = {};
|
|
229
238
|
this.propertyDescriptors.forEach((propertyDescriptor)=>{
|
|
230
239
|
const property = propertyDescriptor.name;
|
|
231
|
-
if (this
|
|
232
|
-
|
|
240
|
+
if (property in this) {
|
|
241
|
+
values[property] = this[property];
|
|
233
242
|
}
|
|
234
243
|
});
|
|
235
|
-
|
|
244
|
+
return values;
|
|
236
245
|
}
|
|
237
246
|
/** @inheritdoc */ revertChanges() {
|
|
238
247
|
this.propertyDescriptors.forEach((propertyDescriptor)=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Command.js","sources":["../../../commands/Command.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ICommand, PropertyChanged } from './ICommand.js';\nimport { CommandResult } from \"./CommandResult.js\";\nimport { CommandValidator } from './CommandValidator.js';\nimport { Constructor, JsonSerializer } from '@cratis/fundamentals';\nimport { Globals } from '../Globals.js';\nimport { joinPaths } from '../joinPaths.js';\nimport { UrlHelpers } from '../UrlHelpers.js';\nimport { GetHttpHeaders } from '../GetHttpHeaders.js';\nimport { PropertyDescriptor } from '../reflection/PropertyDescriptor.js';\nimport { SliceLocation } from '../reflection/SliceLocation.js';\nimport { ValidationResult } from '../validation/ValidationResult.js';\nimport { ValidationResultSeverity } from '../validation/ValidationResultSeverity.js';\nimport { ValidationResultReason } from '../validation/ValidationResultReason.js';\nimport { ValidationResultReasonDetail } from '../validation/ValidationResultReasonDetail.js';\n\ntype Callback = {\n callback: WeakRef<PropertyChanged>;\n thisArg: WeakRef<object>;\n}\n\n/**\n * Represents an implementation of {@link ICommand} that works with HTTP fetch.\n * Missing required properties produce a {@link ValidationResultReason.Rule} result with\n * {@link ValidationResultReasonDetail.Required}, without contacting the server.\n */\nexport abstract class Command<TCommandContent = object, TCommandResponse = object> implements ICommand<TCommandContent, TCommandResponse> {\n /**\n * Gets the {@link SliceLocation} of the command. Generated proxies override it with the location resolved from the backend namespace.\n */\n static readonly sliceLocation: SliceLocation = SliceLocation.empty;\n\n private _microservice: string;\n private _apiBasePath: string;\n private _origin: string;\n private _httpHeadersCallback: GetHttpHeaders;\n abstract readonly route: string;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n readonly validation?: CommandValidator<any>;\n /* eslint-enable @typescript-eslint/no-explicit-any */\n readonly roles: string[] = [];\n /** Inclusive minimum blocking severity declared by a model-bound command proxy. */\n readonly blockOnValidationSeverity?: ValidationResultSeverity;\n abstract readonly propertyDescriptors: PropertyDescriptor[];\n abstract get requestParameters(): string[];\n\n private _initialValues: object = {};\n private _hasChanges = false;\n private _callbacks: Callback[] = [];\n\n /**\n * Initializes a new instance of the {@link Command<,>} class.\n * @param _responseType Type of response.\n * @param _isResponseTypeEnumerable Whether or not the response type is enumerable.\n */\n constructor(readonly _responseType: Constructor = Object, readonly _isResponseTypeEnumerable: boolean) {\n this._microservice = Globals.microservice ?? '';\n this._apiBasePath = Globals.apiBasePath ?? '';\n this._origin = Globals.origin ?? '';\n this._httpHeadersCallback = () => ({});\n }\n\n /** @inheritdoc */\n setMicroservice(microservice: string) {\n this._microservice = microservice;\n }\n\n /** @inheritdoc */\n setApiBasePath(apiBasePath: string): void {\n this._apiBasePath = apiBasePath;\n }\n\n /** @inheritdoc */\n setOrigin(origin: string): void {\n this._origin = origin;\n }\n\n /** @inheritdoc */\n setHttpHeadersCallback(callback: GetHttpHeaders): void {\n this._httpHeadersCallback = callback;\n }\n\n /** @inheritdoc */\n async execute(allowedSeverity?: ValidationResultSeverity, ignoreWarnings?: boolean): Promise<CommandResult<TCommandResponse>> {\n const clientValidationErrors = this.validation?.validate(this) || [];\n const filteredClientErrors = this.filterValidationResultsBySeverity(clientValidationErrors, allowedSeverity, ignoreWarnings);\n if (filteredClientErrors.length > 0) {\n return CommandResult.validationFailed(filteredClientErrors) as CommandResult<TCommandResponse>;\n }\n\n const validationErrors = this.validateRequiredProperties();\n const filteredRequiredErrors = this.filterValidationResultsBySeverity(validationErrors, allowedSeverity, ignoreWarnings);\n if (filteredRequiredErrors.length > 0) {\n return CommandResult.validationFailed(filteredRequiredErrors) as CommandResult<TCommandResponse>;\n }\n\n let actualRoute = this.route;\n\n if (this.requestParameters && this.requestParameters.length > 0) {\n const payload = this.buildPayload();\n const { route } = UrlHelpers.replaceRouteParameters(this.route, payload);\n actualRoute = route;\n }\n\n const result = await this.performRequest(actualRoute, 'Command not found at route', 'Error during server call', allowedSeverity, ignoreWarnings);\n this.setInitialValuesFromCurrentValues();\n return result;\n }\n\n /** @inheritdoc */\n async validate(): Promise<CommandResult<TCommandResponse>> {\n const clientValidationErrors = this.validation?.validate(this) || [];\n const filteredClientErrors = this.filterValidationResultsBySeverity(clientValidationErrors);\n if (filteredClientErrors.length > 0) {\n return CommandResult.validationFailed(filteredClientErrors) as CommandResult<TCommandResponse>;\n }\n\n const validationErrors = this.validateRequiredProperties();\n const filteredRequiredErrors = this.filterValidationResultsBySeverity(validationErrors);\n if (filteredRequiredErrors.length > 0) {\n return CommandResult.validationFailed(filteredRequiredErrors) as CommandResult<TCommandResponse>;\n }\n\n let actualRoute = this.route;\n\n if (this.requestParameters && this.requestParameters.length > 0) {\n const payload = this.buildPayload();\n const { route } = UrlHelpers.replaceRouteParameters(this.route, payload);\n actualRoute = route;\n }\n\n actualRoute = `${actualRoute}/validate`;\n const result = await this.performRequest(actualRoute, 'Command validation endpoint not found at route', 'Error during validation call');\n if (result.isSuccess && clientValidationErrors.length > 0) {\n return Object.assign(result, { validationResults: [...result.validationResults, ...clientValidationErrors] });\n }\n return result;\n }\n\n /** @inheritdoc */\n validateClientSide(): CommandResult<TCommandResponse> {\n const clientValidationErrors = this.validation?.validate(this) || [];\n const filteredClientErrors = this.filterValidationResultsBySeverity(clientValidationErrors);\n if (filteredClientErrors.length > 0) {\n return CommandResult.validationFailed(filteredClientErrors) as CommandResult<TCommandResponse>;\n }\n\n const validationErrors = this.validateRequiredProperties();\n const filteredRequiredErrors = this.filterValidationResultsBySeverity(validationErrors);\n if (filteredRequiredErrors.length > 0) {\n return CommandResult.validationFailed(filteredRequiredErrors) as CommandResult<TCommandResponse>;\n }\n\n const advisoryResults = [...clientValidationErrors, ...validationErrors];\n if (advisoryResults.length === 0) {\n return CommandResult.empty as CommandResult<TCommandResponse>;\n }\n\n return new CommandResult({\n ...CommandResult.empty,\n correlationId: CommandResult.empty.correlationId.toString(),\n validationResults: advisoryResults,\n response: null\n }, Object, false) as CommandResult<TCommandResponse>;\n }\n\n private buildPayload(): object {\n const payload = {};\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n payload[property] = this[property];\n });\n return payload;\n }\n\n private validateRequiredProperties(): ValidationResult[] {\n const validationErrors: ValidationResult[] = [];\n this.propertyDescriptors.forEach(propertyDescriptor => {\n if (!propertyDescriptor.isOptional && !this.requestParameters.includes(propertyDescriptor.name)) {\n const value = this[propertyDescriptor.name];\n if (value === undefined || value === null) {\n validationErrors.push(new ValidationResult(\n ValidationResultSeverity.Error,\n `${propertyDescriptor.name} is required`,\n [propertyDescriptor.name],\n null,\n ValidationResultReason.Rule,\n ValidationResultReasonDetail.Required\n ));\n }\n }\n });\n return validationErrors;\n }\n\n private filterValidationResultsBySeverity(validationResults: ValidationResult[], allowedSeverity?: ValidationResultSeverity, ignoreWarnings?: boolean): ValidationResult[] {\n if (this.blockOnValidationSeverity !== undefined) {\n const effectiveAllowed = Math.min(allowedSeverity ?? ValidationResultSeverity.Error, this.blockOnValidationSeverity - 1);\n return validationResults.filter(result => result.severity === ValidationResultSeverity.Unknown || result.severity > effectiveAllowed);\n }\n if (ignoreWarnings === true) {\n return validationResults.filter(result => result.severity === ValidationResultSeverity.Error);\n }\n if (allowedSeverity === undefined) {\n return validationResults.filter(result => result.severity === ValidationResultSeverity.Error);\n }\n return validationResults.filter(result => result.severity > allowedSeverity);\n }\n\n private buildHeaders(allowedSeverity?: ValidationResultSeverity, ignoreWarnings?: boolean): HeadersInit {\n const customHeaders = this._httpHeadersCallback?.() ?? {};\n const headers = {\n ...customHeaders,\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n };\n\n if (this._microservice?.length > 0) {\n headers[Globals.microserviceHttpHeader] = this._microservice;\n }\n\n if (allowedSeverity !== undefined) {\n headers['X-Allowed-Severity'] = allowedSeverity.toString();\n }\n\n if (ignoreWarnings === true) {\n headers['X-Ignore-Warnings'] = 'true';\n }\n\n return headers;\n }\n\n private async performRequest(\n route: string,\n notFoundMessage: string,\n errorMessage: string,\n allowedSeverity?: ValidationResultSeverity,\n ignoreWarnings?: boolean\n ): Promise<CommandResult<TCommandResponse>> {\n const payload = this.buildPayload();\n const headers = this.buildHeaders(allowedSeverity, ignoreWarnings);\n const actualRoute = joinPaths(this._apiBasePath, route);\n const url = UrlHelpers.createUrlFrom(this._origin, this._apiBasePath, actualRoute);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JsonSerializer.serialize(payload)\n });\n\n if (response.status === 404) {\n return CommandResult.failed([`${notFoundMessage} '${actualRoute}'`]) as CommandResult<TCommandResponse>;\n }\n\n const result = await response.json();\n return new CommandResult(result, this._responseType, this._isResponseTypeEnumerable);\n } catch (ex) {\n return CommandResult.failed([`${errorMessage}: ${ex}`]) as CommandResult<TCommandResponse>;\n }\n }\n\n /** @inheritdoc */\n clear(): void {\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n this[property] = undefined;\n });\n this._initialValues = {};\n this._hasChanges = false;\n }\n\n /** @inheritdoc */\n setInitialValues(values: TCommandContent) {\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n if (Object.prototype.hasOwnProperty.call(values, property)) {\n this._initialValues[property] = values[property];\n this[property] = values[property];\n }\n });\n this.updateHasChanges();\n }\n\n /** @inheritdoc */\n setInitialValuesFromCurrentValues() {\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n if (this[property]) {\n this._initialValues[property] = this[property];\n }\n });\n this.updateHasChanges();\n }\n\n /** @inheritdoc */\n revertChanges(): void {\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n this[property] = this._initialValues[property];\n });\n }\n\n /** @inheritdoc */\n get hasChanges() {\n return this._hasChanges;\n }\n\n /** @inheritdoc */\n propertyChanged(property: string) {\n this.updateHasChanges();\n\n this._callbacks.forEach(callbackContainer => {\n const callback = callbackContainer.callback.deref();\n const thisArg = callbackContainer.thisArg.deref();\n if (callback && thisArg) {\n callback.call(thisArg, property);\n } else {\n this._callbacks = this._callbacks.filter(_ => _.callback !== callbackContainer.callback);\n }\n });\n }\n\n /** @inheritdoc */\n onPropertyChanged(callback: PropertyChanged, thisArg: object) {\n this._callbacks.push({\n callback: new WeakRef(callback),\n thisArg: new WeakRef(thisArg)\n });\n }\n\n private updateHasChanges() {\n this._hasChanges = this.propertyDescriptors.some(propertyDescriptor => {\n const property = propertyDescriptor.name;\n return this[property] !== this._initialValues[property];\n });\n }\n}\n"],"names":["Command","sliceLocation","SliceLocation","empty","_microservice","_apiBasePath","_origin","_httpHeadersCallback","validation","roles","blockOnValidationSeverity","_initialValues","_hasChanges","_callbacks","_responseType","Object","_isResponseTypeEnumerable","Globals","microservice","apiBasePath","origin","setMicroservice","setApiBasePath","setOrigin","setHttpHeadersCallback","callback","execute","allowedSeverity","ignoreWarnings","clientValidationErrors","validate","filteredClientErrors","filterValidationResultsBySeverity","length","CommandResult","validationFailed","validationErrors","validateRequiredProperties","filteredRequiredErrors","actualRoute","route","requestParameters","payload","buildPayload","UrlHelpers","replaceRouteParameters","result","performRequest","setInitialValuesFromCurrentValues","isSuccess","assign","validationResults","validateClientSide","advisoryResults","correlationId","toString","response","propertyDescriptors","forEach","propertyDescriptor","property","name","isOptional","includes","value","undefined","push","ValidationResult","ValidationResultSeverity","Error","ValidationResultReason","Rule","ValidationResultReasonDetail","Required","effectiveAllowed","Math","min","filter","severity","Unknown","buildHeaders","customHeaders","headers","microserviceHttpHeader","notFoundMessage","errorMessage","joinPaths","url","createUrlFrom","fetch","method","body","JsonSerializer","serialize","status","failed","json","ex","clear","setInitialValues","values","prototype","hasOwnProperty","call","updateHasChanges","revertChanges","hasChanges","propertyChanged","callbackContainer","deref","thisArg","_","onPropertyChanged","WeakRef","some"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Command.js","sources":["../../../commands/Command.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ICommand, PropertyChanged } from './ICommand.js';\nimport { CommandResult } from \"./CommandResult.js\";\nimport { CommandValidator } from './CommandValidator.js';\nimport { Constructor, JsonSerializer } from '@cratis/fundamentals';\nimport { Globals } from '../Globals.js';\nimport { joinPaths } from '../joinPaths.js';\nimport { UrlHelpers } from '../UrlHelpers.js';\nimport { GetHttpHeaders } from '../GetHttpHeaders.js';\nimport { PropertyDescriptor } from '../reflection/PropertyDescriptor.js';\nimport { SliceLocation } from '../reflection/SliceLocation.js';\nimport { ValidationResult } from '../validation/ValidationResult.js';\nimport { ValidationResultSeverity } from '../validation/ValidationResultSeverity.js';\nimport { ValidationResultReason } from '../validation/ValidationResultReason.js';\nimport { ValidationResultReasonDetail } from '../validation/ValidationResultReasonDetail.js';\n\ntype Callback = {\n callback: WeakRef<PropertyChanged>;\n thisArg: WeakRef<object>;\n}\n\n/**\n * Represents an implementation of {@link ICommand} that works with HTTP fetch.\n * Missing required properties produce a {@link ValidationResultReason.Rule} result with\n * {@link ValidationResultReasonDetail.Required}, without contacting the server.\n */\nexport abstract class Command<TCommandContent = object, TCommandResponse = object> implements ICommand<TCommandContent, TCommandResponse> {\n /**\n * Gets the {@link SliceLocation} of the command. Generated proxies override it with the location resolved from the backend namespace.\n */\n static readonly sliceLocation: SliceLocation = SliceLocation.empty;\n\n private _microservice: string;\n private _apiBasePath: string;\n private _origin: string;\n private _httpHeadersCallback: GetHttpHeaders;\n abstract readonly route: string;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n readonly validation?: CommandValidator<any>;\n /* eslint-enable @typescript-eslint/no-explicit-any */\n readonly roles: string[] = [];\n /** Inclusive minimum blocking severity declared by a model-bound command proxy. */\n readonly blockOnValidationSeverity?: ValidationResultSeverity;\n abstract readonly propertyDescriptors: PropertyDescriptor[];\n abstract get requestParameters(): string[];\n\n private _initialValues: object = {};\n private _hasChanges = false;\n private _callbacks: Callback[] = [];\n\n /**\n * Initializes a new instance of the {@link Command<,>} class.\n * @param _responseType Type of response.\n * @param _isResponseTypeEnumerable Whether or not the response type is enumerable.\n */\n constructor(readonly _responseType: Constructor = Object, readonly _isResponseTypeEnumerable: boolean) {\n this._microservice = Globals.microservice ?? '';\n this._apiBasePath = Globals.apiBasePath ?? '';\n this._origin = Globals.origin ?? '';\n this._httpHeadersCallback = () => ({});\n }\n\n /** @inheritdoc */\n setMicroservice(microservice: string) {\n this._microservice = microservice;\n }\n\n /** @inheritdoc */\n setApiBasePath(apiBasePath: string): void {\n this._apiBasePath = apiBasePath;\n }\n\n /** @inheritdoc */\n setOrigin(origin: string): void {\n this._origin = origin;\n }\n\n /** @inheritdoc */\n setHttpHeadersCallback(callback: GetHttpHeaders): void {\n this._httpHeadersCallback = callback;\n }\n\n /** @inheritdoc */\n async execute(allowedSeverity?: ValidationResultSeverity, ignoreWarnings?: boolean): Promise<CommandResult<TCommandResponse>> {\n const clientValidationErrors = this.validation?.validate(this) || [];\n const filteredClientErrors = this.filterValidationResultsBySeverity(clientValidationErrors, allowedSeverity, ignoreWarnings);\n if (filteredClientErrors.length > 0) {\n return CommandResult.validationFailed(filteredClientErrors) as CommandResult<TCommandResponse>;\n }\n\n const validationErrors = this.validateRequiredProperties();\n const filteredRequiredErrors = this.filterValidationResultsBySeverity(validationErrors, allowedSeverity, ignoreWarnings);\n if (filteredRequiredErrors.length > 0) {\n return CommandResult.validationFailed(filteredRequiredErrors) as CommandResult<TCommandResponse>;\n }\n\n let actualRoute = this.route;\n\n if (this.requestParameters && this.requestParameters.length > 0) {\n const payload = this.buildPayload();\n const { route } = UrlHelpers.replaceRouteParameters(this.route, payload);\n actualRoute = route;\n }\n\n const submittedValues = this.captureCurrentValues();\n const result = await this.performRequest(actualRoute, 'Command not found at route', 'Error during server call', allowedSeverity, ignoreWarnings);\n if (result.isSuccess) {\n this._initialValues = submittedValues;\n this.updateHasChanges();\n }\n return result;\n }\n\n /** @inheritdoc */\n async validate(): Promise<CommandResult<TCommandResponse>> {\n const clientValidationErrors = this.validation?.validate(this) || [];\n const filteredClientErrors = this.filterValidationResultsBySeverity(clientValidationErrors);\n if (filteredClientErrors.length > 0) {\n return CommandResult.validationFailed(filteredClientErrors) as CommandResult<TCommandResponse>;\n }\n\n const validationErrors = this.validateRequiredProperties();\n const filteredRequiredErrors = this.filterValidationResultsBySeverity(validationErrors);\n if (filteredRequiredErrors.length > 0) {\n return CommandResult.validationFailed(filteredRequiredErrors) as CommandResult<TCommandResponse>;\n }\n\n let actualRoute = this.route;\n\n if (this.requestParameters && this.requestParameters.length > 0) {\n const payload = this.buildPayload();\n const { route } = UrlHelpers.replaceRouteParameters(this.route, payload);\n actualRoute = route;\n }\n\n actualRoute = `${actualRoute}/validate`;\n const result = await this.performRequest(actualRoute, 'Command validation endpoint not found at route', 'Error during validation call');\n if (result.isSuccess && clientValidationErrors.length > 0) {\n return Object.assign(result, { validationResults: [...result.validationResults, ...clientValidationErrors] });\n }\n return result;\n }\n\n /** @inheritdoc */\n validateClientSide(): CommandResult<TCommandResponse> {\n const clientValidationErrors = this.validation?.validate(this) || [];\n const filteredClientErrors = this.filterValidationResultsBySeverity(clientValidationErrors);\n if (filteredClientErrors.length > 0) {\n return CommandResult.validationFailed(filteredClientErrors) as CommandResult<TCommandResponse>;\n }\n\n const validationErrors = this.validateRequiredProperties();\n const filteredRequiredErrors = this.filterValidationResultsBySeverity(validationErrors);\n if (filteredRequiredErrors.length > 0) {\n return CommandResult.validationFailed(filteredRequiredErrors) as CommandResult<TCommandResponse>;\n }\n\n const advisoryResults = [...clientValidationErrors, ...validationErrors];\n if (advisoryResults.length === 0) {\n return CommandResult.empty as CommandResult<TCommandResponse>;\n }\n\n return new CommandResult({\n ...CommandResult.empty,\n correlationId: CommandResult.empty.correlationId.toString(),\n validationResults: advisoryResults,\n response: null\n }, Object, false) as CommandResult<TCommandResponse>;\n }\n\n private buildPayload(): object {\n const payload = {};\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n payload[property] = this[property];\n });\n return payload;\n }\n\n private validateRequiredProperties(): ValidationResult[] {\n const validationErrors: ValidationResult[] = [];\n this.propertyDescriptors.forEach(propertyDescriptor => {\n if (!propertyDescriptor.isOptional && !this.requestParameters.includes(propertyDescriptor.name)) {\n const value = this[propertyDescriptor.name];\n if (value === undefined || value === null) {\n validationErrors.push(new ValidationResult(\n ValidationResultSeverity.Error,\n `${propertyDescriptor.name} is required`,\n [propertyDescriptor.name],\n null,\n ValidationResultReason.Rule,\n ValidationResultReasonDetail.Required\n ));\n }\n }\n });\n return validationErrors;\n }\n\n private filterValidationResultsBySeverity(validationResults: ValidationResult[], allowedSeverity?: ValidationResultSeverity, ignoreWarnings?: boolean): ValidationResult[] {\n if (this.blockOnValidationSeverity !== undefined) {\n const effectiveAllowed = Math.min(allowedSeverity ?? ValidationResultSeverity.Error, this.blockOnValidationSeverity - 1);\n return validationResults.filter(result => result.severity === ValidationResultSeverity.Unknown || result.severity > effectiveAllowed);\n }\n if (ignoreWarnings === true) {\n return validationResults.filter(result => result.severity === ValidationResultSeverity.Error);\n }\n if (allowedSeverity === undefined) {\n return validationResults.filter(result => result.severity === ValidationResultSeverity.Error);\n }\n return validationResults.filter(result => result.severity > allowedSeverity);\n }\n\n private buildHeaders(allowedSeverity?: ValidationResultSeverity, ignoreWarnings?: boolean): HeadersInit {\n const customHeaders = this._httpHeadersCallback?.() ?? {};\n const headers = {\n ...customHeaders,\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n };\n\n if (this._microservice?.length > 0) {\n headers[Globals.microserviceHttpHeader] = this._microservice;\n }\n\n if (allowedSeverity !== undefined) {\n headers['X-Allowed-Severity'] = allowedSeverity.toString();\n }\n\n if (ignoreWarnings === true) {\n headers['X-Ignore-Warnings'] = 'true';\n }\n\n return headers;\n }\n\n private async performRequest(\n route: string,\n notFoundMessage: string,\n errorMessage: string,\n allowedSeverity?: ValidationResultSeverity,\n ignoreWarnings?: boolean\n ): Promise<CommandResult<TCommandResponse>> {\n const payload = this.buildPayload();\n const headers = this.buildHeaders(allowedSeverity, ignoreWarnings);\n const actualRoute = joinPaths(this._apiBasePath, route);\n const url = UrlHelpers.createUrlFrom(this._origin, this._apiBasePath, actualRoute);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JsonSerializer.serialize(payload)\n });\n\n if (response.status === 404) {\n return CommandResult.failed([`${notFoundMessage} '${actualRoute}'`]) as CommandResult<TCommandResponse>;\n }\n\n const result = await response.json();\n return new CommandResult(result, this._responseType, this._isResponseTypeEnumerable);\n } catch (ex) {\n return CommandResult.failed([`${errorMessage}: ${ex}`]) as CommandResult<TCommandResponse>;\n }\n }\n\n /** @inheritdoc */\n clear(): void {\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n this[property] = undefined;\n });\n this._initialValues = {};\n this._hasChanges = false;\n }\n\n /** @inheritdoc */\n setInitialValues(values: TCommandContent) {\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n if (Object.prototype.hasOwnProperty.call(values, property)) {\n this._initialValues[property] = values[property];\n this[property] = values[property];\n }\n });\n this.updateHasChanges();\n }\n\n /** @inheritdoc */\n setInitialValuesFromCurrentValues() {\n this._initialValues = this.captureCurrentValues();\n this.updateHasChanges();\n }\n\n private captureCurrentValues(): object {\n const values = {};\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n if (property in this) {\n values[property] = this[property];\n }\n });\n return values;\n }\n\n /** @inheritdoc */\n revertChanges(): void {\n this.propertyDescriptors.forEach(propertyDescriptor => {\n const property = propertyDescriptor.name;\n this[property] = this._initialValues[property];\n });\n }\n\n /** @inheritdoc */\n get hasChanges() {\n return this._hasChanges;\n }\n\n /** @inheritdoc */\n propertyChanged(property: string) {\n this.updateHasChanges();\n\n this._callbacks.forEach(callbackContainer => {\n const callback = callbackContainer.callback.deref();\n const thisArg = callbackContainer.thisArg.deref();\n if (callback && thisArg) {\n callback.call(thisArg, property);\n } else {\n this._callbacks = this._callbacks.filter(_ => _.callback !== callbackContainer.callback);\n }\n });\n }\n\n /** @inheritdoc */\n onPropertyChanged(callback: PropertyChanged, thisArg: object) {\n this._callbacks.push({\n callback: new WeakRef(callback),\n thisArg: new WeakRef(thisArg)\n });\n }\n\n private updateHasChanges() {\n this._hasChanges = this.propertyDescriptors.some(propertyDescriptor => {\n const property = propertyDescriptor.name;\n return this[property] !== this._initialValues[property];\n });\n }\n}\n"],"names":["Command","sliceLocation","SliceLocation","empty","_microservice","_apiBasePath","_origin","_httpHeadersCallback","validation","roles","blockOnValidationSeverity","_initialValues","_hasChanges","_callbacks","_responseType","Object","_isResponseTypeEnumerable","Globals","microservice","apiBasePath","origin","setMicroservice","setApiBasePath","setOrigin","setHttpHeadersCallback","callback","execute","allowedSeverity","ignoreWarnings","clientValidationErrors","validate","filteredClientErrors","filterValidationResultsBySeverity","length","CommandResult","validationFailed","validationErrors","validateRequiredProperties","filteredRequiredErrors","actualRoute","route","requestParameters","payload","buildPayload","UrlHelpers","replaceRouteParameters","submittedValues","captureCurrentValues","result","performRequest","isSuccess","updateHasChanges","assign","validationResults","validateClientSide","advisoryResults","correlationId","toString","response","propertyDescriptors","forEach","propertyDescriptor","property","name","isOptional","includes","value","undefined","push","ValidationResult","ValidationResultSeverity","Error","ValidationResultReason","Rule","ValidationResultReasonDetail","Required","effectiveAllowed","Math","min","filter","severity","Unknown","buildHeaders","customHeaders","headers","microserviceHttpHeader","notFoundMessage","errorMessage","joinPaths","url","createUrlFrom","fetch","method","body","JsonSerializer","serialize","status","failed","json","ex","clear","setInitialValues","values","prototype","hasOwnProperty","call","setInitialValuesFromCurrentValues","revertChanges","hasChanges","propertyChanged","callbackContainer","deref","thisArg","_","onPropertyChanged","WeakRef","some"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from '../Command.js';
|
|
2
|
+
import { PropertyDescriptor } from '../../reflection/PropertyDescriptor.js';
|
|
3
|
+
export declare class GeneratedCommand extends Command<{
|
|
4
|
+
value: unknown;
|
|
5
|
+
}> {
|
|
6
|
+
#private;
|
|
7
|
+
readonly route = "/save";
|
|
8
|
+
readonly propertyDescriptors: PropertyDescriptor[];
|
|
9
|
+
constructor();
|
|
10
|
+
get requestParameters(): string[];
|
|
11
|
+
get properties(): string[];
|
|
12
|
+
get value(): unknown;
|
|
13
|
+
set value(value: unknown);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=GeneratedCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GeneratedCommand.d.ts","sourceRoot":"","sources":["../../../../commands/for_Command/GeneratedCommand.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAE5E,qBAAa,gBAAiB,SAAQ,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;;IAC7D,QAAQ,CAAC,KAAK,WAAW;IACzB,QAAQ,CAAC,mBAAmB,uBAAmD;IAG/E,cAEC;IAED,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAEhC;IAED,IAAI,UAAU,IAAI,MAAM,EAAE,CAEzB;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,EAGvB;CACJ"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Command } from '../Command.js';
|
|
2
|
+
import { PropertyDescriptor } from '../../reflection/PropertyDescriptor.js';
|
|
3
|
+
export class GeneratedCommand extends Command {
|
|
4
|
+
route = '/save';
|
|
5
|
+
propertyDescriptors = [new PropertyDescriptor('value', Object, true)];
|
|
6
|
+
#value;
|
|
7
|
+
constructor() {
|
|
8
|
+
super(Object, false);
|
|
9
|
+
}
|
|
10
|
+
get requestParameters() {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
get properties() {
|
|
14
|
+
return ['value'];
|
|
15
|
+
}
|
|
16
|
+
get value() {
|
|
17
|
+
return this.#value;
|
|
18
|
+
}
|
|
19
|
+
set value(value) {
|
|
20
|
+
this.#value = value;
|
|
21
|
+
this.propertyChanged('value');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=GeneratedCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GeneratedCommand.js","sourceRoot":"","sources":["../../../../commands/for_Command/GeneratedCommand.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAE5E,MAAM,OAAO,gBAAiB,SAAQ,OAA2B;IACpD,KAAK,GAAG,OAAO,CAAC;IAChB,mBAAmB,GAAG,CAAC,IAAI,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/E,MAAM,CAAU;IAEhB;QACI,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,IAAI,iBAAiB;QACjB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,IAAI,UAAU;QACV,OAAO,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,IAAI,KAAK,CAAC,KAAc;QACpB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_a_failed_submission.d.ts","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_a_failed_submission.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { a_command } from '../given/a_command.js';
|
|
2
|
+
for (const failure of ['server rejection', 'not found', 'network error', 'invalid JSON']) {
|
|
3
|
+
describe(`when executing with ${failure}`, () => {
|
|
4
|
+
let context;
|
|
5
|
+
beforeEach(async () => {
|
|
6
|
+
context = new a_command();
|
|
7
|
+
context.command.setInitialValues({ someProperty: 'accepted' });
|
|
8
|
+
context.command.someProperty = 'rejected';
|
|
9
|
+
context.command.propertyChanged('someProperty');
|
|
10
|
+
if (failure === 'network error') {
|
|
11
|
+
context.fetchStub.rejects(new Error('offline'));
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
context.fetchStub.resolves({
|
|
15
|
+
status: failure === 'not found' ? 404 : 200,
|
|
16
|
+
json: async () => {
|
|
17
|
+
if (failure === 'invalid JSON') {
|
|
18
|
+
throw new Error('invalid JSON');
|
|
19
|
+
}
|
|
20
|
+
return { correlationId: '00000000-0000-0000-0000-000000000000', isSuccess: false, validationResults: [], exceptionMessages: ['rejected'] };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
await context.command.execute();
|
|
25
|
+
});
|
|
26
|
+
afterEach(() => context.fetchHelper.restore());
|
|
27
|
+
it('should keep the command dirty', () => context.command.hasChanges.should.be.true);
|
|
28
|
+
it('should revert to the last accepted values', () => {
|
|
29
|
+
context.command.revertChanges();
|
|
30
|
+
context.command.someProperty.should.equal('accepted');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=with_a_failed_submission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_a_failed_submission.js","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_a_failed_submission.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,KAAK,MAAM,OAAO,IAAI,CAAC,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,CAAC,EAAE,CAAC;IACvF,QAAQ,CAAC,uBAAuB,OAAO,EAAE,EAAE,GAAG,EAAE;QAC5C,IAAI,OAAkB,CAAC;QAEvB,UAAU,CAAC,KAAK,IAAI,EAAE;YAClB,OAAO,GAAG,IAAI,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,OAAO,CAAC,YAAY,GAAG,UAAU,CAAC;YAC1C,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YAEhD,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;gBAC9B,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC;oBACvB,MAAM,EAAE,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;oBAC3C,IAAI,EAAE,KAAK,IAAI,EAAE;wBACb,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;4BAC7B,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;wBACpC,CAAC;wBACD,OAAO,EAAE,aAAa,EAAE,sCAAsC,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC/I,CAAC;iBACJ,CAAC,CAAC;YACP,CAAC;YACD,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAE/C,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QACrF,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACjD,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAChC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_an_edit_during_submission.d.ts","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_an_edit_during_submission.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { a_command } from '../given/a_command.js';
|
|
2
|
+
describe('when executing with an edit during submission', () => {
|
|
3
|
+
let context;
|
|
4
|
+
beforeEach(async () => {
|
|
5
|
+
context = new a_command();
|
|
6
|
+
context.command.setInitialValues({ someProperty: 'accepted' });
|
|
7
|
+
context.command.someProperty = 'submitted';
|
|
8
|
+
context.command.propertyChanged('someProperty');
|
|
9
|
+
let complete;
|
|
10
|
+
context.fetchStub.returns(new Promise(resolve => { complete = resolve; }));
|
|
11
|
+
const execution = context.command.execute();
|
|
12
|
+
context.command.someProperty = 'unsent edit';
|
|
13
|
+
context.command.propertyChanged('someProperty');
|
|
14
|
+
complete({ status: 200, json: async () => ({ correlationId: '00000000-0000-0000-0000-000000000000', isSuccess: true, validationResults: [] }) });
|
|
15
|
+
await execution;
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => context.fetchHelper.restore());
|
|
18
|
+
it('should send the submitted value', () => JSON.parse(context.fetchStub.firstCall.args[1].body).someProperty.should.equal('submitted'));
|
|
19
|
+
it('should preserve the unsent edit', () => context.command.someProperty.should.equal('unsent edit'));
|
|
20
|
+
it('should keep the command dirty', () => context.command.hasChanges.should.be.true);
|
|
21
|
+
it('should revert to the submitted value', () => {
|
|
22
|
+
context.command.revertChanges();
|
|
23
|
+
context.command.someProperty.should.equal('submitted');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=with_an_edit_during_submission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_an_edit_during_submission.js","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_an_edit_during_submission.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAC3D,IAAI,OAAkB,CAAC;IAEvB,UAAU,CAAC,KAAK,IAAI,EAAE;QAClB,OAAO,GAAG,IAAI,SAAS,EAAE,CAAC;QAC1B,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,OAAO,CAAC,YAAY,GAAG,WAAW,CAAC;QAC3C,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;QAChD,IAAI,QAAqC,CAAC;QAC1C,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3E,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5C,OAAO,CAAC,OAAO,CAAC,YAAY,GAAG,aAAa,CAAC;QAC7C,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;QAChD,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,sCAAsC,EAAE,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACjJ,MAAM,SAAS,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAE/C,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IACzI,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IACtG,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACrF,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC5C,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAChC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
package/dist/esm/commands/for_Command/when_executing/with_generated_property_accessors.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_generated_property_accessors.d.ts","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_generated_property_accessors.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { GeneratedCommand } from '../GeneratedCommand.js';
|
|
2
|
+
import { createFetchHelper } from '../../../helpers/fetchHelper.js';
|
|
3
|
+
for (const value of ['submitted', '', 0, false, null, undefined]) {
|
|
4
|
+
for (const isSuccess of [true, false]) {
|
|
5
|
+
describe(`when executing generated property accessors with ${String(value)} and success is ${isSuccess}`, () => {
|
|
6
|
+
let command;
|
|
7
|
+
let fetchHelper;
|
|
8
|
+
let fetchStub;
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
command = new GeneratedCommand();
|
|
11
|
+
command.setOrigin('http://localhost');
|
|
12
|
+
command.setInitialValues({ value: 'accepted' });
|
|
13
|
+
command.value = value;
|
|
14
|
+
fetchHelper = createFetchHelper();
|
|
15
|
+
fetchStub = fetchHelper.stubFetch();
|
|
16
|
+
fetchStub.resolves({ status: 200, json: async () => ({ correlationId: '00000000-0000-0000-0000-000000000000', isSuccess, validationResults: [] }) });
|
|
17
|
+
await command.execute();
|
|
18
|
+
});
|
|
19
|
+
afterEach(() => fetchHelper.restore());
|
|
20
|
+
it('should only accept successful submissions as clean', () => command.hasChanges.should.equal(!isSuccess));
|
|
21
|
+
it('should revert to the last accepted value', () => {
|
|
22
|
+
command.value = 'later edit';
|
|
23
|
+
command.revertChanges();
|
|
24
|
+
(command.value === (isSuccess ? value : 'accepted')).should.be.true;
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
describe('when capturing current values through generated property accessors', () => {
|
|
30
|
+
let command;
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
command = new GeneratedCommand();
|
|
33
|
+
command.value = false;
|
|
34
|
+
command.setInitialValuesFromCurrentValues();
|
|
35
|
+
});
|
|
36
|
+
it('should capture the current value as clean', () => command.hasChanges.should.be.false);
|
|
37
|
+
it('should revert through the setter to the captured value', () => {
|
|
38
|
+
command.value = 'later edit';
|
|
39
|
+
command.revertChanges();
|
|
40
|
+
(command.value === false).should.be.true;
|
|
41
|
+
command.hasChanges.should.be.false;
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=with_generated_property_accessors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_generated_property_accessors.js","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_generated_property_accessors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,KAAK,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;IAC/D,KAAK,MAAM,SAAS,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QACpC,QAAQ,CAAC,oDAAoD,MAAM,CAAC,KAAK,CAAC,mBAAmB,SAAS,EAAE,EAAE,GAAG,EAAE;YAC3G,IAAI,OAAyB,CAAC;YAC9B,IAAI,WAAiD,CAAC;YACtD,IAAI,SAA0B,CAAC;YAE/B,UAAU,CAAC,KAAK,IAAI,EAAE;gBAClB,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAC;gBACjC,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;gBACtC,OAAO,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;gBAChD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;gBACtB,WAAW,GAAG,iBAAiB,EAAE,CAAC;gBAClC,SAAS,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC;gBACpC,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,sCAAsC,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;gBACrJ,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAC5B,CAAC,CAAC,CAAC;YAEH,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YAEvC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YAC5G,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;gBAChD,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC;gBAC7B,OAAO,CAAC,aAAa,EAAE,CAAC;gBACxB,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;YACxE,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,oEAAoE,EAAE,GAAG,EAAE;IAChF,IAAI,OAAyB,CAAC;IAE9B,UAAU,CAAC,GAAG,EAAE;QACZ,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;QACtB,OAAO,CAAC,iCAAiC,EAAE,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAC1F,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAC9D,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC;QAC7B,OAAO,CAAC,aAAa,EAAE,CAAC;QACxB,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;QACzC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;IACvC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_submitted_falsy_values.d.ts","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_submitted_falsy_values.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { a_command } from '../given/a_command.js';
|
|
2
|
+
import { PropertyDescriptor } from '../../../reflection/PropertyDescriptor.js';
|
|
3
|
+
for (const value of ['', 0, false, null, undefined]) {
|
|
4
|
+
describe(`when executing with submitted value ${String(value)}`, () => {
|
|
5
|
+
let context;
|
|
6
|
+
beforeEach(async () => {
|
|
7
|
+
context = new a_command();
|
|
8
|
+
context.command.propertyDescriptors = [new PropertyDescriptor('someProperty', String, true)];
|
|
9
|
+
context.command.setInitialValues({ someProperty: 'accepted' });
|
|
10
|
+
context.command.someProperty = value;
|
|
11
|
+
context.command.propertyChanged('someProperty');
|
|
12
|
+
context.fetchStub.resolves({ status: 200, json: async () => ({ correlationId: '00000000-0000-0000-0000-000000000000', isSuccess: true, validationResults: [] }) });
|
|
13
|
+
await context.command.execute();
|
|
14
|
+
});
|
|
15
|
+
afterEach(() => context.fetchHelper.restore());
|
|
16
|
+
it('should accept the submitted value as clean', () => context.command.hasChanges.should.be.false);
|
|
17
|
+
it('should revert to the submitted value', () => {
|
|
18
|
+
context.command.someProperty = 'later edit';
|
|
19
|
+
context.command.revertChanges();
|
|
20
|
+
(context.command.someProperty === value).should.be.true;
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=with_submitted_falsy_values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_submitted_falsy_values.js","sourceRoot":"","sources":["../../../../../commands/for_Command/when_executing/with_submitted_falsy_values.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAE/E,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;IAClD,QAAQ,CAAC,uCAAuC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE;QAClE,IAAI,OAAkB,CAAC;QAEvB,UAAU,CAAC,KAAK,IAAI,EAAE;YAClB,OAAO,GAAG,IAAI,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,OAAO,CAAC,mBAAmB,GAAG,CAAC,IAAI,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;YAC7F,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,OAAO,CAAC,YAAY,GAAG,KAA0B,CAAC;YAC1D,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YAChD,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,sCAAsC,EAAE,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YACnK,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAE/C,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACnG,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC5C,OAAO,CAAC,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC;YAC5C,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAChC,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;QAC5D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/esm/commands/for_Command/when_setting_initial_values_from_current_values.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"when_setting_initial_values_from_current_values.d.ts","sourceRoot":"","sources":["../../../../commands/for_Command/when_setting_initial_values_from_current_values.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SomeCommand } from './SomeCommand.js';
|
|
2
|
+
for (const value of ['', 0, false, null, undefined, 'missing']) {
|
|
3
|
+
describe(`when setting initial values from current value ${String(value)}`, () => {
|
|
4
|
+
let command;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
command = new SomeCommand();
|
|
7
|
+
command.setInitialValues({ someProperty: 'accepted' });
|
|
8
|
+
if (value === 'missing') {
|
|
9
|
+
Reflect.deleteProperty(command, 'someProperty');
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
command.someProperty = value;
|
|
13
|
+
}
|
|
14
|
+
command.setInitialValuesFromCurrentValues();
|
|
15
|
+
});
|
|
16
|
+
it('should mark the current values as clean', () => command.hasChanges.should.be.false);
|
|
17
|
+
it('should revert to the captured value', () => {
|
|
18
|
+
command.someProperty = 'later edit';
|
|
19
|
+
command.revertChanges();
|
|
20
|
+
(command.someProperty === (value === 'missing' ? undefined : value)).should.be.true;
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=when_setting_initial_values_from_current_values.js.map
|