@cratis/arc 20.3.1 → 20.3.2
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/dist/cjs/queries/ObservableQueryConnectionFactory.js +11 -2
- package/dist/cjs/queries/ObservableQueryConnectionFactory.js.map +1 -1
- package/dist/cjs/queries/ObservableQueryMultiplexer.d.ts +1 -1
- package/dist/cjs/queries/ObservableQueryMultiplexer.d.ts.map +1 -1
- package/dist/cjs/queries/ObservableQueryMultiplexer.js +2 -2
- package/dist/cjs/queries/ObservableQueryMultiplexer.js.map +1 -1
- package/dist/cjs/queries/QueryInstanceCache.d.ts +0 -1
- package/dist/cjs/queries/QueryInstanceCache.d.ts.map +1 -1
- package/dist/cjs/queries/QueryInstanceCache.js +10 -25
- package/dist/cjs/queries/QueryInstanceCache.js.map +1 -1
- package/dist/cjs/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.d.ts +2 -0
- package/dist/cjs/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.d.ts.map +1 -0
- package/dist/cjs/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.d.ts +2 -0
- package/dist/cjs/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.d.ts.map +1 -0
- package/dist/cjs/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.d.ts +2 -0
- package/dist/cjs/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.d.ts.map +1 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.d.ts +2 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.d.ts.map +1 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.d.ts +2 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.d.ts.map +1 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.d.ts +2 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.d.ts.map +1 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.d.ts +2 -0
- package/dist/cjs/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.d.ts.map +1 -0
- package/dist/cjs/queries/for_QueryInstanceCache/when_acquiring/after_release.d.ts +2 -0
- package/dist/cjs/queries/for_QueryInstanceCache/when_acquiring/after_release.d.ts.map +1 -0
- package/dist/esm/queries/ObservableQueryConnectionFactory.js +11 -2
- package/dist/esm/queries/ObservableQueryConnectionFactory.js.map +1 -1
- package/dist/esm/queries/ObservableQueryMultiplexer.d.ts +1 -1
- package/dist/esm/queries/ObservableQueryMultiplexer.d.ts.map +1 -1
- package/dist/esm/queries/ObservableQueryMultiplexer.js +2 -2
- package/dist/esm/queries/ObservableQueryMultiplexer.js.map +1 -1
- package/dist/esm/queries/QueryInstanceCache.d.ts +0 -1
- package/dist/esm/queries/QueryInstanceCache.d.ts.map +1 -1
- package/dist/esm/queries/QueryInstanceCache.js +10 -25
- package/dist/esm/queries/QueryInstanceCache.js.map +1 -1
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.js +55 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.js.map +1 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.js +49 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.js.map +1 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.js +48 -0
- package/dist/esm/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.js.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.js +32 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.js.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.js +23 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.js.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.js +23 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.js.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.js +25 -0
- package/dist/esm/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.js.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_acquiring/after_release.d.ts +2 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_acquiring/after_release.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_acquiring/after_release.js +23 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_acquiring/after_release.js.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_releasing/the_only_subscriber_outside_development_mode.js +4 -1
- package/dist/esm/queries/for_QueryInstanceCache/when_releasing/the_only_subscriber_outside_development_mode.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/queries/ObservableQueryConnectionFactory.ts +23 -2
- package/queries/ObservableQueryMultiplexer.ts +3 -2
- package/queries/QueryInstanceCache.ts +27 -42
- package/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.ts +69 -0
- package/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.ts +61 -0
- package/queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.ts +60 -0
- package/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.ts +42 -0
- package/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.ts +34 -0
- package/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.ts +33 -0
- package/queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.ts +35 -0
- package/queries/for_QueryInstanceCache/when_acquiring/after_release.ts +31 -0
- package/queries/for_QueryInstanceCache/when_releasing/the_only_subscriber_outside_development_mode.ts +4 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryInstanceCache.d.ts","sourceRoot":"","sources":["../../../queries/QueryInstanceCache.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAK9D,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAKnC,MAAM,MAAM,kBAAkB,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;AAM9F,MAAM,WAAW,eAAe,CAAC,SAAS;IAItC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAK3B,UAAU,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAK7C,eAAe,EAAE,MAAM,CAAC;IAKxB,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;IAMvD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAKtB,UAAU,EAAE,OAAO,CAAC;IAOpB,cAAc,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;CAClD;AAUD,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsD;IAC/E,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"QueryInstanceCache.d.ts","sourceRoot":"","sources":["../../../queries/QueryInstanceCache.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAK9D,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAKnC,MAAM,MAAM,kBAAkB,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;AAM9F,MAAM,WAAW,eAAe,CAAC,SAAS;IAItC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAK3B,UAAU,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAK7C,eAAe,EAAE,MAAM,CAAC;IAKxB,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;IAMvD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAKtB,UAAU,EAAE,OAAO,CAAC;IAOpB,cAAc,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;CAClD;AAUD,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsD;IAC/E,OAAO,CAAC,eAAe,CAAC,CAAgC;gBAQ5C,WAAW,GAAE,OAAe;IAWxC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa;IAuB7D,WAAW,CAAC,SAAS,EACjB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,MAAM,SAAS,GACzB;QAAE,QAAQ,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE;IAyB1C,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAmBjC,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,GAAG,oBAAoB,CAAC,SAAS,CAAC,GAAG,SAAS;IAUzF,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,oBAAoB,CAAC,SAAS,CAAC,GAAG,IAAI;IAkB3F,WAAW,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,kBAAkB,CAAC,SAAS,CAAC,GAAG,IAAI;IAczF,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,kBAAkB,CAAC,SAAS,CAAC,GAAG,IAAI;IAc5F,WAAW,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAc3D,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO;IAYzC,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IA6BjC,GAAG,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO;IAchC,wBAAwB,IAAI,IAAI;IAkBhC,OAAO,IAAI,IAAI;IAwBf,YAAY,IAAI,IAAI;IAiBpB,oBAAoB,IAAI,IAAI;CAM/B"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
class QueryInstanceCache {
|
|
2
2
|
_entries = new Map();
|
|
3
|
-
_development;
|
|
4
3
|
_pendingDispose;
|
|
5
4
|
constructor(development = false) {
|
|
6
|
-
this._development = development;
|
|
7
5
|
}
|
|
8
6
|
buildKey(queryTypeName, args) {
|
|
9
7
|
if (!args || Object.keys(args).length === 0) {
|
|
@@ -81,29 +79,16 @@ class QueryInstanceCache {
|
|
|
81
79
|
if (entry) {
|
|
82
80
|
entry.subscriberCount--;
|
|
83
81
|
if (entry.subscriberCount <= 0) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}, 0);
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
entry.subscribed = false;
|
|
98
|
-
entry.teardown?.();
|
|
99
|
-
entry.teardown = undefined;
|
|
100
|
-
setTimeout(() => {
|
|
101
|
-
const current = this._entries.get(key);
|
|
102
|
-
if (current && current.subscriberCount <= 0) {
|
|
103
|
-
this._entries.delete(key);
|
|
104
|
-
}
|
|
105
|
-
}, 0);
|
|
106
|
-
}
|
|
82
|
+
entry.pendingCleanup = setTimeout(() => {
|
|
83
|
+
const current = this._entries.get(key);
|
|
84
|
+
if (current && current.subscriberCount <= 0) {
|
|
85
|
+
current.subscribed = false;
|
|
86
|
+
current.teardown?.();
|
|
87
|
+
current.teardown = undefined;
|
|
88
|
+
current.pendingCleanup = undefined;
|
|
89
|
+
this._entries.delete(key);
|
|
90
|
+
}
|
|
91
|
+
}, 0);
|
|
107
92
|
}
|
|
108
93
|
}
|
|
109
94
|
}
|
|
@@ -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';\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> = (result: QueryResultWithState<TDataType>) => 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 when running in development mode.\n * Allows React StrictMode re-mounts to cancel the pending teardown\n * so the connection is reused instead of 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 readonly _development: boolean;\n private _pendingDispose?: ReturnType<typeof setTimeout>;\n\n /**\n * Initializes a new instance of {@link QueryInstanceCache}.\n * @param development When true, teardown is deferred on release so React StrictMode\n * re-mounts can re-acquire the entry without an unnecessary disconnect/reconnect cycle.\n */\n constructor(development: boolean = false) {\n this._development = development;\n }\n\n /**\n * Builds the cache key for a query.\n * @param queryTypeName The name of the query constructor (i.e. `constructor.name`).\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} in development mode),\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>(key: QueryCacheKey): QueryResultWithState<TDataType> | undefined {\n return this._entries.get(key)?.lastResult as QueryResultWithState<TDataType> | 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>(key: QueryCacheKey, result: QueryResultWithState<TDataType>): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.lastResult = result as QueryResultWithState<unknown>;\n\n for (const listener of entry.listeners) {\n (listener as QueryCacheListener<TDataType>)(result);\n }\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>(key: QueryCacheKey, listener: QueryCacheListener<TDataType>): 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>(key: QueryCacheKey, listener: QueryCacheListener<TDataType>): 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 the teardown\n * function is called (if set) and the entry is evicted.\n *\n * In development mode, both teardown and eviction are deferred by one microtask so that\n * React StrictMode re-mounts can re-acquire the entry and cancel the cleanup. This prevents\n * an unnecessary disconnect/reconnect cycle during the synthetic unmount/remount that\n * StrictMode performs in development builds.\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 if (this._development) {\n // Defer both teardown and deletion so StrictMode re-mounts can cancel.\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 }, 0);\n } else {\n entry.subscribed = false;\n entry.teardown?.();\n entry.teardown = undefined;\n\n // Defer deletion so React Strict Mode re-mounts can re-acquire the entry.\n setTimeout(() => {\n const current = this._entries.get(key);\n\n if (current && current.subscriberCount <= 0) {\n this._entries.delete(key);\n }\n }, 0);\n }\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"],"names":[],"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';\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> = (result: QueryResultWithState<TDataType>) => 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 development Accepted for API compatibility. No longer changes teardown behavior —\n * teardown is always deferred to handle React StrictMode re-mounts in any environment.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n constructor(development: boolean = false) {\n // The development parameter is kept for API compatibility only.\n // Teardown is always deferred regardless of this flag.\n }\n\n /**\n * Builds the cache key for a query.\n * @param queryTypeName The name of the query constructor (i.e. `constructor.name`).\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>(key: QueryCacheKey): QueryResultWithState<TDataType> | undefined {\n return this._entries.get(key)?.lastResult as QueryResultWithState<TDataType> | 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>(key: QueryCacheKey, result: QueryResultWithState<TDataType>): void {\n const entry = this._entries.get(key);\n\n if (entry) {\n entry.lastResult = result as QueryResultWithState<unknown>;\n\n for (const listener of entry.listeners) {\n (listener as QueryCacheListener<TDataType>)(result);\n }\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>(key: QueryCacheKey, listener: QueryCacheListener<TDataType>): 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>(key: QueryCacheKey, listener: QueryCacheListener<TDataType>): 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 deletion so React StrictMode re-mounts in any environment\n // can cancel by calling acquire() before the timeout fires.\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 }, 0);\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"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.d.ts","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { a_descriptor } from '../given/a_descriptor';
|
|
2
|
+
import { given } from '../../../given';
|
|
3
|
+
import { Globals } from '../../../Globals';
|
|
4
|
+
import { QueryTransportMethod } from '../../QueryTransportMethod';
|
|
5
|
+
import { createObservableQueryConnection } from '../../ObservableQueryConnectionFactory';
|
|
6
|
+
import { MultiplexedObservableQueryConnection, resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
7
|
+
import * as sinon from 'sinon';
|
|
8
|
+
describe('when creating with hub mode and SSE transport and connection count exceeding safe limit', given(a_descriptor, context => {
|
|
9
|
+
let connection;
|
|
10
|
+
let warnStub;
|
|
11
|
+
let originalConnectionCount;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
originalConnectionCount = Globals.queryConnectionCount;
|
|
14
|
+
Globals.queryDirectMode = false;
|
|
15
|
+
Globals.queryTransportMethod = QueryTransportMethod.ServerSentEvents;
|
|
16
|
+
Globals.queryConnectionCount = 10;
|
|
17
|
+
warnStub = sinon.stub(console, 'warn');
|
|
18
|
+
const FakeEventSourceConstructor = function () {
|
|
19
|
+
Object.assign(this, {
|
|
20
|
+
onopen: null,
|
|
21
|
+
onerror: null,
|
|
22
|
+
onmessage: null,
|
|
23
|
+
close: sinon.stub(),
|
|
24
|
+
addEventListener: sinon.stub(),
|
|
25
|
+
removeEventListener: sinon.stub(),
|
|
26
|
+
readyState: 0,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
globalThis['EventSource'] = FakeEventSourceConstructor;
|
|
30
|
+
globalThis['fetch'] = sinon.stub().resolves({ ok: true });
|
|
31
|
+
connection = createObservableQueryConnection(context.descriptor);
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
Globals.queryDirectMode = context.originalDirectMode;
|
|
35
|
+
Globals.queryTransportMethod = context.originalTransportMethod;
|
|
36
|
+
Globals.queryConnectionCount = originalConnectionCount;
|
|
37
|
+
warnStub.restore();
|
|
38
|
+
delete globalThis['EventSource'];
|
|
39
|
+
delete globalThis['fetch'];
|
|
40
|
+
resetSharedMultiplexer();
|
|
41
|
+
});
|
|
42
|
+
it('should return a MultiplexedObservableQueryConnection', () => {
|
|
43
|
+
connection.should.be.instanceOf(MultiplexedObservableQueryConnection);
|
|
44
|
+
});
|
|
45
|
+
it('should log a warning about the connection count limit', () => {
|
|
46
|
+
warnStub.calledOnce.should.be.true;
|
|
47
|
+
});
|
|
48
|
+
it('should mention the requested connection count in the warning', () => {
|
|
49
|
+
warnStub.firstCall.args[0].should.include('10');
|
|
50
|
+
});
|
|
51
|
+
it('should mention the safe limit in the warning', () => {
|
|
52
|
+
warnStub.firstCall.args[0].should.include('4');
|
|
53
|
+
});
|
|
54
|
+
}));
|
|
55
|
+
//# sourceMappingURL=with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.js","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_exceeding_safe_limit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.d.ts","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { a_descriptor } from '../given/a_descriptor';
|
|
2
|
+
import { given } from '../../../given';
|
|
3
|
+
import { Globals } from '../../../Globals';
|
|
4
|
+
import { QueryTransportMethod } from '../../QueryTransportMethod';
|
|
5
|
+
import { createObservableQueryConnection } from '../../ObservableQueryConnectionFactory';
|
|
6
|
+
import { MultiplexedObservableQueryConnection, resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
7
|
+
import * as sinon from 'sinon';
|
|
8
|
+
describe('when creating with hub mode and SSE transport and connection count within safe limit', given(a_descriptor, context => {
|
|
9
|
+
let connection;
|
|
10
|
+
let warnStub;
|
|
11
|
+
let originalConnectionCount;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
originalConnectionCount = Globals.queryConnectionCount;
|
|
14
|
+
Globals.queryDirectMode = false;
|
|
15
|
+
Globals.queryTransportMethod = QueryTransportMethod.ServerSentEvents;
|
|
16
|
+
Globals.queryConnectionCount = 4;
|
|
17
|
+
warnStub = sinon.stub(console, 'warn');
|
|
18
|
+
const FakeEventSourceConstructor = function () {
|
|
19
|
+
Object.assign(this, {
|
|
20
|
+
onopen: null,
|
|
21
|
+
onerror: null,
|
|
22
|
+
onmessage: null,
|
|
23
|
+
close: sinon.stub(),
|
|
24
|
+
addEventListener: sinon.stub(),
|
|
25
|
+
removeEventListener: sinon.stub(),
|
|
26
|
+
readyState: 0,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
globalThis['EventSource'] = FakeEventSourceConstructor;
|
|
30
|
+
globalThis['fetch'] = sinon.stub().resolves({ ok: true });
|
|
31
|
+
connection = createObservableQueryConnection(context.descriptor);
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
Globals.queryDirectMode = context.originalDirectMode;
|
|
35
|
+
Globals.queryTransportMethod = context.originalTransportMethod;
|
|
36
|
+
Globals.queryConnectionCount = originalConnectionCount;
|
|
37
|
+
warnStub.restore();
|
|
38
|
+
delete globalThis['EventSource'];
|
|
39
|
+
delete globalThis['fetch'];
|
|
40
|
+
resetSharedMultiplexer();
|
|
41
|
+
});
|
|
42
|
+
it('should return a MultiplexedObservableQueryConnection', () => {
|
|
43
|
+
connection.should.be.instanceOf(MultiplexedObservableQueryConnection);
|
|
44
|
+
});
|
|
45
|
+
it('should not log a warning', () => {
|
|
46
|
+
warnStub.called.should.be.false;
|
|
47
|
+
});
|
|
48
|
+
}));
|
|
49
|
+
//# sourceMappingURL=with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.js","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_sse_transport_and_connection_count_within_safe_limit.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,wCAAwC,CAAC;AACzF,OAAO,EAAE,oCAAoC,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAGhH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,QAAQ,CAAC,sFAAsF,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE;IAC3H,IAAI,UAA+C,CAAC;IACpD,IAAI,QAAyB,CAAC;IAC9B,IAAI,uBAA+B,CAAC;IAEpC,UAAU,CAAC,GAAG,EAAE;QACZ,uBAAuB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACvD,OAAO,CAAC,eAAe,GAAG,KAAK,CAAC;QAChC,OAAO,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,gBAAgB,CAAC;QACrE,OAAO,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAEjC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAEvC,MAAM,0BAA0B,GAAG;YAC/B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;gBAChB,MAAM,EAAE,IAAI;gBACZ,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;gBACnB,gBAAgB,EAAE,KAAK,CAAC,IAAI,EAAE;gBAC9B,mBAAmB,EAAE,KAAK,CAAC,IAAI,EAAE;gBACjC,UAAU,EAAE,CAAC;aAChB,CAAC,CAAC;QACP,CAAC,CAAC;QACD,UAAsC,CAAC,aAAa,CAAC,GAAG,0BAA0B,CAAC;QACnF,UAAsC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,IAAI,EAAc,CAAC,CAAC;QAEnG,UAAU,GAAG,+BAA+B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,CAAC;QAC/D,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC;QACvD,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnB,OAAQ,UAAsC,CAAC,aAAa,CAAC,CAAC;QAC9D,OAAQ,UAAsC,CAAC,OAAO,CAAC,CAAC;QACxD,sBAAsB,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC5D,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,oCAAoC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_hub_mode_and_websocket_transport_and_high_connection_count.d.ts","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { a_descriptor } from '../given/a_descriptor';
|
|
2
|
+
import { given } from '../../../given';
|
|
3
|
+
import { Globals } from '../../../Globals';
|
|
4
|
+
import { QueryTransportMethod } from '../../QueryTransportMethod';
|
|
5
|
+
import { createObservableQueryConnection } from '../../ObservableQueryConnectionFactory';
|
|
6
|
+
import { MultiplexedObservableQueryConnection, resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
7
|
+
import * as sinon from 'sinon';
|
|
8
|
+
describe('when creating with hub mode and WebSocket transport and high connection count', given(a_descriptor, context => {
|
|
9
|
+
let connection;
|
|
10
|
+
let warnStub;
|
|
11
|
+
let originalConnectionCount;
|
|
12
|
+
let originalWebSocket;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
originalConnectionCount = Globals.queryConnectionCount;
|
|
15
|
+
Globals.queryDirectMode = false;
|
|
16
|
+
Globals.queryTransportMethod = QueryTransportMethod.WebSocket;
|
|
17
|
+
Globals.queryConnectionCount = 10;
|
|
18
|
+
warnStub = sinon.stub(console, 'warn');
|
|
19
|
+
originalWebSocket = global.WebSocket;
|
|
20
|
+
global.WebSocket = function () {
|
|
21
|
+
return {
|
|
22
|
+
onopen: null,
|
|
23
|
+
onclose: null,
|
|
24
|
+
onerror: null,
|
|
25
|
+
onmessage: null,
|
|
26
|
+
close: sinon.stub(),
|
|
27
|
+
send: sinon.stub(),
|
|
28
|
+
readyState: 0,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
connection = createObservableQueryConnection(context.descriptor);
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
Globals.queryDirectMode = context.originalDirectMode;
|
|
35
|
+
Globals.queryTransportMethod = context.originalTransportMethod;
|
|
36
|
+
Globals.queryConnectionCount = originalConnectionCount;
|
|
37
|
+
warnStub.restore();
|
|
38
|
+
global.WebSocket = originalWebSocket;
|
|
39
|
+
resetSharedMultiplexer();
|
|
40
|
+
});
|
|
41
|
+
it('should return a MultiplexedObservableQueryConnection', () => {
|
|
42
|
+
connection.should.be.instanceOf(MultiplexedObservableQueryConnection);
|
|
43
|
+
});
|
|
44
|
+
it('should not log a warning', () => {
|
|
45
|
+
warnStub.called.should.be.false;
|
|
46
|
+
});
|
|
47
|
+
}));
|
|
48
|
+
//# sourceMappingURL=with_hub_mode_and_websocket_transport_and_high_connection_count.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_hub_mode_and_websocket_transport_and_high_connection_count.js","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryConnectionFactory/when_creating/with_hub_mode_and_websocket_transport_and_high_connection_count.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,wCAAwC,CAAC;AACzF,OAAO,EAAE,oCAAoC,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAGhH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,QAAQ,CAAC,+EAA+E,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE;IACpH,IAAI,UAA+C,CAAC;IACpD,IAAI,QAAyB,CAAC;IAC9B,IAAI,uBAA+B,CAAC;IACpC,IAAI,iBAAmC,CAAC;IAExC,UAAU,CAAC,GAAG,EAAE;QACZ,uBAAuB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACvD,OAAO,CAAC,eAAe,GAAG,KAAK,CAAC;QAChC,OAAO,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,SAAS,CAAC;QAC9D,OAAO,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAElC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAEvC,iBAAiB,GAAG,MAAM,CAAC,SAAS,CAAC;QACpC,MAAkC,CAAC,SAAS,GAAG;YAC5C,OAAO;gBACH,MAAM,EAAE,IAAI;gBACZ,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;gBACnB,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;gBAClB,UAAU,EAAE,CAAC;aAChB,CAAC;QACN,CAAC,CAAC;QAEF,UAAU,GAAG,+BAA+B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,CAAC;QAC/D,OAAO,CAAC,oBAAoB,GAAG,uBAAuB,CAAC;QACvD,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACrC,sBAAsB,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC5D,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,oCAAoC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_a_changed_cache_key.d.ts","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getOrCreateMultiplexer, resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
2
|
+
describe('when getting or creating with a changed cache key', () => {
|
|
3
|
+
let factoryCallCount;
|
|
4
|
+
let disposedConnectionCount;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
factoryCallCount = 0;
|
|
7
|
+
disposedConnectionCount = 0;
|
|
8
|
+
const factory = () => {
|
|
9
|
+
factoryCallCount++;
|
|
10
|
+
return {
|
|
11
|
+
queryCount: 0,
|
|
12
|
+
lastPingLatency: 0,
|
|
13
|
+
averageLatency: 0,
|
|
14
|
+
subscribe: () => { },
|
|
15
|
+
unsubscribe: () => { },
|
|
16
|
+
dispose: () => { disposedConnectionCount++; },
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
getOrCreateMultiplexer(factory, 'key-one', 1);
|
|
20
|
+
getOrCreateMultiplexer(factory, 'key-two', 1);
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
resetSharedMultiplexer();
|
|
24
|
+
});
|
|
25
|
+
it('should dispose the connections of the previous multiplexer', () => {
|
|
26
|
+
disposedConnectionCount.should.be.greaterThan(0);
|
|
27
|
+
});
|
|
28
|
+
it('should create connections for both multiplexers', () => {
|
|
29
|
+
factoryCallCount.should.equal(2);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=with_a_changed_cache_key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_a_changed_cache_key.js","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_changed_cache_key.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAIlG,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC/D,IAAI,gBAAwB,CAAC;IAC7B,IAAI,uBAA+B,CAAC;IAEpC,UAAU,CAAC,GAAG,EAAE;QACZ,gBAAgB,GAAG,CAAC,CAAC;QACrB,uBAAuB,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,GAAkC,EAAE;YAChD,gBAAgB,EAAE,CAAC;YACnB,OAAO;gBACH,UAAU,EAAE,CAAC;gBACb,eAAe,EAAE,CAAC;gBAClB,cAAc,EAAE,CAAC;gBACjB,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC;gBACnB,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;gBACrB,OAAO,EAAE,GAAG,EAAE,GAAG,uBAAuB,EAAE,CAAC,CAAC,CAAC;aAChD,CAAC;QACN,CAAC,CAAC;QACF,sBAAsB,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAC9C,sBAAsB,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,sBAAsB,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QAClE,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACvD,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_a_new_cache_key.d.ts","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getOrCreateMultiplexer, ObservableQueryMultiplexer, resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
2
|
+
describe('when getting or creating with a new cache key', () => {
|
|
3
|
+
let multiplexer;
|
|
4
|
+
let factoryCallCount;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
factoryCallCount = 0;
|
|
7
|
+
const factory = () => {
|
|
8
|
+
factoryCallCount++;
|
|
9
|
+
return { queryCount: 0, lastPingLatency: 0, averageLatency: 0, subscribe: () => { }, unsubscribe: () => { }, dispose: () => { } };
|
|
10
|
+
};
|
|
11
|
+
multiplexer = getOrCreateMultiplexer(factory, 'test-key', 1);
|
|
12
|
+
});
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
resetSharedMultiplexer();
|
|
15
|
+
});
|
|
16
|
+
it('should return a multiplexer', () => {
|
|
17
|
+
multiplexer.should.be.instanceOf(ObservableQueryMultiplexer);
|
|
18
|
+
});
|
|
19
|
+
it('should call the factory to create connections', () => {
|
|
20
|
+
factoryCallCount.should.be.greaterThan(0);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=with_a_new_cache_key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_a_new_cache_key.js","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_a_new_cache_key.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAI9H,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAC3D,IAAI,WAAuC,CAAC;IAC5C,IAAI,gBAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACZ,gBAAgB,GAAG,CAAC,CAAC;QACrB,MAAM,OAAO,GAAG,GAAkC,EAAE;YAChD,gBAAgB,EAAE,CAAC;YACnB,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;QACnI,CAAC,CAAC;QACF,WAAW,GAAG,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,sBAAsB,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACrD,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_an_explicit_size.d.ts","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getOrCreateMultiplexer, resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
2
|
+
describe('when getting or creating with an explicit size', () => {
|
|
3
|
+
let multiplexer;
|
|
4
|
+
let factoryCallCount;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
factoryCallCount = 0;
|
|
7
|
+
const factory = () => {
|
|
8
|
+
factoryCallCount++;
|
|
9
|
+
return { queryCount: 0, lastPingLatency: 0, averageLatency: 0, subscribe: () => { }, unsubscribe: () => { }, dispose: () => { } };
|
|
10
|
+
};
|
|
11
|
+
multiplexer = getOrCreateMultiplexer(factory, 'test-key', 3);
|
|
12
|
+
});
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
resetSharedMultiplexer();
|
|
15
|
+
});
|
|
16
|
+
it('should create a multiplexer with the given size', () => {
|
|
17
|
+
multiplexer.size.should.equal(3);
|
|
18
|
+
});
|
|
19
|
+
it('should create exactly that many connections', () => {
|
|
20
|
+
factoryCallCount.should.equal(3);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=with_an_explicit_size.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_an_explicit_size.js","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_an_explicit_size.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAA8B,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAI9H,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC5D,IAAI,WAAuC,CAAC;IAC5C,IAAI,gBAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACZ,gBAAgB,GAAG,CAAC,CAAC;QACrB,MAAM,OAAO,GAAG,GAAkC,EAAE;YAChD,gBAAgB,EAAE,CAAC;YACnB,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;QACnI,CAAC,CAAC;QACF,WAAW,GAAG,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,sBAAsB,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACvD,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_the_same_cache_key.d.ts","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getOrCreateMultiplexer, resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
2
|
+
describe('when getting or creating with the same cache key', () => {
|
|
3
|
+
let first;
|
|
4
|
+
let second;
|
|
5
|
+
let factoryCallCount;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
factoryCallCount = 0;
|
|
8
|
+
const factory = () => {
|
|
9
|
+
factoryCallCount++;
|
|
10
|
+
return { queryCount: 0, lastPingLatency: 0, averageLatency: 0, subscribe: () => { }, unsubscribe: () => { }, dispose: () => { } };
|
|
11
|
+
};
|
|
12
|
+
first = getOrCreateMultiplexer(factory, 'test-key', 1);
|
|
13
|
+
second = getOrCreateMultiplexer(factory, 'test-key', 1);
|
|
14
|
+
});
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
resetSharedMultiplexer();
|
|
17
|
+
});
|
|
18
|
+
it('should return the same instance', () => {
|
|
19
|
+
second.should.equal(first);
|
|
20
|
+
});
|
|
21
|
+
it('should only call the factory once', () => {
|
|
22
|
+
factoryCallCount.should.equal(1);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=with_the_same_cache_key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with_the_same_cache_key.js","sourceRoot":"","sources":["../../../../../queries/for_ObservableQueryMultiplexer/when_getting_or_creating/with_the_same_cache_key.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAA8B,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAI9H,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAC9D,IAAI,KAAiC,CAAC;IACtC,IAAI,MAAkC,CAAC;IACvC,IAAI,gBAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACZ,gBAAgB,GAAG,CAAC,CAAC;QACrB,MAAM,OAAO,GAAG,GAAkC,EAAE;YAChD,gBAAgB,EAAE,CAAC;YACnB,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;QACnI,CAAC,CAAC;QACF,KAAK,GAAG,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QACvD,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,sBAAsB,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"after_release.d.ts","sourceRoot":"","sources":["../../../../../queries/for_QueryInstanceCache/when_acquiring/after_release.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { QueryInstanceCache } from '../../QueryInstanceCache';
|
|
2
|
+
describe('when acquiring after release', () => {
|
|
3
|
+
let cache;
|
|
4
|
+
let teardownCalled;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
vi.useFakeTimers();
|
|
7
|
+
teardownCalled = false;
|
|
8
|
+
cache = new QueryInstanceCache();
|
|
9
|
+
cache.getOrCreate('MyQuery::', () => ({}));
|
|
10
|
+
cache.acquire('MyQuery::');
|
|
11
|
+
cache.setTeardown('MyQuery::', () => { teardownCalled = true; });
|
|
12
|
+
cache.release('MyQuery::');
|
|
13
|
+
cache.acquire('MyQuery::');
|
|
14
|
+
vi.advanceTimersByTime(0);
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
vi.useRealTimers();
|
|
18
|
+
});
|
|
19
|
+
it('should not call teardown', () => teardownCalled.should.be.false);
|
|
20
|
+
it('should keep the entry', () => cache.has('MyQuery::').should.be.true);
|
|
21
|
+
it('should still report as subscribed', () => cache.isSubscribed('MyQuery::').should.be.true);
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=after_release.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"after_release.js","sourceRoot":"","sources":["../../../../../queries/for_QueryInstanceCache/when_acquiring/after_release.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC1C,IAAI,KAAyB,CAAC;IAC9B,IAAI,cAAuB,CAAC;IAE5B,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,cAAc,GAAG,KAAK,CAAC;QACvB,KAAK,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACjC,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC3B,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAG3B,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC3B,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACrE,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACzE,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AAClG,CAAC,CAAC,CAAC"}
|
|
@@ -14,11 +14,14 @@ describe('when releasing the only subscriber outside development mode', () => {
|
|
|
14
14
|
afterEach(() => {
|
|
15
15
|
vi.useRealTimers();
|
|
16
16
|
});
|
|
17
|
-
it('should call teardown synchronously', () => teardownCalled.should.be.
|
|
17
|
+
it('should not call teardown synchronously', () => teardownCalled.should.be.false);
|
|
18
|
+
it('should keep the entry before the timer fires', () => cache.has('MyQuery::').should.be.true);
|
|
19
|
+
it('should still report as subscribed before the timer fires', () => cache.isSubscribed('MyQuery::').should.be.true);
|
|
18
20
|
describe('and the deferred timer fires', () => {
|
|
19
21
|
beforeEach(() => {
|
|
20
22
|
vi.advanceTimersByTime(0);
|
|
21
23
|
});
|
|
24
|
+
it('should call teardown', () => teardownCalled.should.be.true);
|
|
22
25
|
it('should evict the entry', () => cache.has('MyQuery::').should.be.false);
|
|
23
26
|
});
|
|
24
27
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"the_only_subscriber_outside_development_mode.js","sourceRoot":"","sources":["../../../../../queries/for_QueryInstanceCache/when_releasing/the_only_subscriber_outside_development_mode.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;IACzE,IAAI,KAAyB,CAAC;IAC9B,IAAI,cAAuB,CAAC;IAE5B,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,cAAc,GAAG,KAAK,CAAC;QACvB,KAAK,GAAG,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACtC,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC3B,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"the_only_subscriber_outside_development_mode.js","sourceRoot":"","sources":["../../../../../queries/for_QueryInstanceCache/when_releasing/the_only_subscriber_outside_development_mode.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;IACzE,IAAI,KAAyB,CAAC;IAC9B,IAAI,cAAuB,CAAC;IAE5B,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,cAAc,GAAG,KAAK,CAAC;QACvB,KAAK,GAAG,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACtC,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC3B,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACnF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAChG,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAErH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;QAC1C,UAAU,CAAC,GAAG,EAAE;YACZ,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAChE,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|