@craft-ng/core 0.0.1 → 0.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"craft-ng-core.mjs","sources":["../../../../libs/core/src/lib/util/util.ts","../../../../libs/core/src/lib/after-recomputation.ts","../../../../libs/core/src/lib/preserved-resource.ts","../../../../libs/core/src/lib/util/resource-by-id-changes-tracker.util.ts","../../../../libs/core/src/lib/resource-by-id.ts","../../../../libs/core/src/lib/craft-resource.ts","../../../../libs/core/src/lib/async-process.ts","../../../../libs/core/src/lib/computed-source.ts","../../../../libs/core/src/lib/signal-proxy.ts","../../../../libs/core/src/lib/craft.ts","../../../../libs/core/src/lib/craft-async-process.ts","../../../../libs/core/src/lib/craft-computed.ts","../../../../libs/core/src/lib/craft-inject.ts","../../../../libs/core/src/lib/craft-inputs.ts","../../../../libs/core/src/lib/craft-mutations.ts","../../../../libs/core/src/lib/craft-query-param.ts","../../../../libs/core/src/lib/craft-query-params.ts","../../../../libs/core/src/lib/craft-query.ts","../../../../libs/core/src/lib/craft-set-all-queries-params-standalone.ts","../../../../libs/core/src/lib/craft-sources.ts","../../../../libs/core/src/lib/craft-state.ts","../../../../libs/core/src/lib/util/persister.util.ts","../../../../libs/core/src/lib/util/explicit-effect.ts","../../../../libs/core/src/lib/util/types/util.ts","../../../../libs/core/src/lib/local-storage-persister.ts","../../../../libs/core/src/lib/insert-local-storage-persister.ts","../../../../libs/core/src/lib/linked-source.ts","../../../../libs/core/src/lib/mutation.ts","../../../../libs/core/src/lib/query-param.ts","../../../../libs/core/src/lib/query.ts","../../../../libs/core/src/lib/signal-source.ts","../../../../libs/core/src/lib/source-from-event.ts","../../../../libs/core/src/lib/stacked-source.ts","../../../../libs/core/src/lib/state.ts","../../../../libs/core/src/lib/to-source.ts","../../../../libs/core/src/lib/util/util.type.ts","../../../../libs/core/src/lib/util/update-state.util.ts","../../../../libs/core/src/lib/query.core.ts","../../../../libs/core/src/lib/util/react-on-mutation-effect.ts","../../../../libs/core/src/lib/insert-react-on-mutation.ts","../../../../libs/core/src/lib/insert-pagination-placeholder-data.ts","../../../../libs/core/src/lib/global-persister-handler.service.ts","../../../../libs/core/src/lib/util/entities-util.ts","../../../../libs/core/src/lib/reactive-writable-signal.ts","../../../../libs/core/src/lib/source$.ts","../../../../libs/core/src/craft-ng-core.ts"],"sourcesContent":["import { effect, untracked, WritableSignal } from '@angular/core';\nimport { ReadonlySource } from './source.type';\n\nexport const SourceBrand = Symbol('SourceBrand');\n\nexport const SourceBranded = {\n [SourceBrand]: true as const,\n};\n\nexport type SourceBranded = {\n [SourceBrand]: true;\n};\n\n/**\n * Works for Source and ReadonlySource\n */\nexport function isSource(value: any): boolean {\n return value && SourceBrand in value;\n}\n\nexport type SourceBrand = typeof SourceBrand;\n\nexport function capitalize<S extends string>(str: S): Capitalize<S> {\n return (str.charAt(0).toUpperCase() + str.slice(1)) as Capitalize<S>;\n}\n\nexport function createMethodHandlers<State>(\n methodsData:\n | Record<\n string,\n ((...args: any[]) => NoInfer<State>) | ReadonlySource<State>\n >\n | undefined,\n state: WritableSignal<State>,\n options?: {\n onStateChange?: (newValue: State) => void;\n },\n) {\n const { methodsConnectedToSource, methods } = Object.entries(\n methodsData ?? {},\n ).reduce(\n (acc, [methodName, methodValue]) => {\n if (isSource(methodValue)) {\n acc.methodsConnectedToSource.push(\n methodValue as ReadonlySource<unknown>,\n );\n return acc;\n }\n acc.methods[methodName] = methodValue as Function;\n return acc;\n },\n {\n methodsConnectedToSource: [],\n methods: {},\n } as {\n methodsConnectedToSource: ReadonlySource<unknown>[];\n methods: Record<string, Function>;\n },\n );\n\n const finalMethods = Object.entries(methods ?? {}).reduce(\n (acc, [methodName, method]) => {\n acc[methodName] = (...args: any[]) => {\n const result = method(...args);\n state.set(result);\n options?.onStateChange?.(result);\n };\n return acc;\n },\n {} as Record<string, Function>,\n );\n\n methodsConnectedToSource.forEach((sourceSignal) => {\n effect(() => {\n const newValue = sourceSignal();\n untracked(() => {\n if (newValue !== undefined) {\n state.set(newValue as NoInfer<State>);\n }\n });\n });\n });\n return finalMethods;\n}\n","import { effect, signal, untracked } from '@angular/core';\nimport { SignalSource } from './signal-source';\nimport { ReadonlySource } from './util/source.type';\nimport { SourceBranded } from './util/util';\n\n/**\n * Creates a derived readonly source that transforms source emissions through a callback function.\n *\n * This function binds queries, mutations, and async methods to sources for automatic execution by:\n * - Listening to source emissions and computing new values\n * - Providing a readonly source suitable for method binding\n * - Maintaining reactivity through Angular's effect system\n * - Enabling source-based triggering patterns\n *\n * @remarks\n * **Primary Use Case:**\n * Bind queries/mutations/async methods to sources for automatic execution:\n * ```ts\n * method: afterRecomputation(mySource, (data) => data)\n * ```\n * This pattern makes queries/mutations execute automatically when the source emits.\n *\n * **Execution Flow:**\n * 1. Source emits a value via `source.set(value)`\n * 2. afterRecomputation callback transforms the value\n * 3. Resulting readonly source emits the transformed value\n * 4. Bound query/mutation/async method executes with the new value\n *\n * **Difference from computedSource:**\n * - `afterRecomputation`: Designed for binding to method parameters\n * - `computedSource`: General-purpose source transformation\n * - Both transform source values, but afterRecomputation is optimized for method binding\n *\n * **Common Patterns:**\n * - **Identity transformation**: `afterRecomputation(source, (x) => x)` - pass value through\n * - **Field extraction**: `afterRecomputation(source, (data) => data.id)` - extract specific field\n * - **Validation**: `afterRecomputation(source, (data) => validate(data))` - transform and validate\n * - **Mapping**: `afterRecomputation(source, (data) => mapToDto(data))` - convert to different type\n *\n * @template State - The type of values produced by the callback\n * @template SourceType - The type of values emitted by the origin source\n *\n * @param _source - The source to listen to.\n * When this source emits, the callback is invoked.\n *\n * @param callback - Function that transforms source values.\n * Receives the emitted value and returns the transformed result.\n *\n * @returns A readonly source that emits transformed values.\n * Can be used as the `method` parameter in queries, mutations, and async methods.\n *\n * @example\n * Binding a query to a source for automatic execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * userIdChange: source<string>(),\n * }),\n * craftQuery('user', ({ userIdChange }) =>\n * query({\n * method: afterRecomputation(userIdChange, (userId) => userId),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Query executes automatically when source emits\n * store.setUserIdChange('user-123');\n * // -> query loader executes with params 'user-123'\n *\n * store.setUserIdChange('user-456');\n * // -> query loader executes again with params 'user-456'\n * ```\n *\n * @example\n * Binding a mutation to a source\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * submitForm: source<{ name: string; email: string }>(),\n * }),\n * craftMutations(({ submitForm }) => ({\n * submit: mutation({\n * method: afterRecomputation(submitForm, (formData) => formData),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Mutation executes automatically when source emits\n * store.setSubmitForm({ name: 'John', email: 'john@example.com' });\n * // -> mutation loader executes with form data\n * // Note: No store.mutateSubmit method exposed (source-based)\n * ```\n *\n * @example\n * Binding async method to a source\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * searchInput: source<string>(),\n * }),\n * craftAsyncProcesses(({ searchInput }) => ({\n * search: asyncProcess({\n * method: afterRecomputation(searchInput, (term) => term),\n * loader: async ({ params }) => {\n * // Debounce at source level before setting\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Async method executes automatically\n * store.setSearchInput('query');\n * // -> search loader executes\n * ```\n *\n * @example\n * Extracting specific field from complex data\n * ```ts\n * type FormData = {\n * user: { id: string; name: string };\n * address: { city: string };\n * };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * formSubmit: source<FormData>(),\n * }),\n * craftMutations(({ formSubmit }) => ({\n * updateUser: mutation({\n * // Extract only user data\n * method: afterRecomputation(formSubmit, (data) => data.user),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Only user data is passed to mutation\n * store.setFormSubmit({\n * user: { id: 'user-1', name: 'John' },\n * address: { city: 'NYC' },\n * });\n * // -> mutation receives only { id: 'user-1', name: 'John' }\n * ```\n *\n * @example\n * Transforming data before execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * searchParams: source<{ query: string; filters: string[] }>(),\n * }),\n * craftQuery('results', ({ searchParams }) =>\n * query({\n * method: afterRecomputation(searchParams, (params) => ({\n * q: params.query.trim().toLowerCase(),\n * f: params.filters.join(','),\n * })),\n * loader: async ({ params }) => {\n * const query = new URLSearchParams(params);\n * const response = await fetch(`/api/search?${query}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Data is transformed before query execution\n * store.setSearchParams({\n * query: ' Angular ',\n * filters: ['tutorial', 'advanced'],\n * });\n * // -> query receives { q: 'angular', f: 'tutorial,advanced' }\n * ```\n *\n * @example\n * Validation and type narrowing\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * inputChange: source<string>(),\n * }),\n * craftAsyncProcesses(({ inputChange }) => ({\n * validate: asyncProcess({\n * method: afterRecomputation(inputChange, (input) => {\n * // Only proceed if input is valid\n * const trimmed = input.trim();\n * if (trimmed.length < 3) {\n * throw new Error('Input too short');\n * }\n * return trimmed;\n * }),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/validate', {\n * method: 'POST',\n * body: JSON.stringify({ input: params }),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Invalid input throws error in callback\n * store.setInputChange('ab'); // Error: Input too short\n *\n * // Valid input proceeds\n * store.setInputChange('valid input'); // Validation executes\n * ```\n *\n * @example\n * Multiple sources with different transformations\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * quickSearch: source<string>(),\n * advancedSearch: source<{ query: string; options: unknown }>(),\n * }),\n * craftQuery('searchResults', ({ quickSearch, advancedSearch }) =>\n * query({\n * method: afterRecomputation(\n * // Can combine sources at higher level\n * quickSearch, // For this example, using one source\n * (term) => ({ query: term, mode: 'quick' })\n * ),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/search', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Quick search with simple string\n * store.setQuickSearch('angular');\n * // -> query receives { query: 'angular', mode: 'quick' }\n * ```\n *\n * @example\n * Identity transformation (pass-through)\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * dataUpdate: source<{ id: string; payload: unknown }>(),\n * }),\n * craftMutations(({ dataUpdate }) => ({\n * update: mutation({\n * // Pass data through unchanged\n * method: afterRecomputation(dataUpdate, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/data/${params.id}`, {\n * method: 'PUT',\n * body: JSON.stringify(params.payload),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Data passed through unchanged\n * store.setDataUpdate({ id: 'item-1', payload: { value: 123 } });\n * // -> mutation receives exact same object\n * ```\n */\nexport function afterRecomputation<State, SourceType>(\n _source: SignalSource<SourceType>,\n callback: (source: SourceType) => State,\n): ReadonlySource<State> {\n const derivedSource = signal<State | undefined>(undefined);\n const effectRef = effect(() => {\n const sourceValue = _source();\n if (sourceValue !== undefined) {\n untracked(() => {\n const newState = callback(sourceValue);\n derivedSource.set(newState);\n });\n } else {\n derivedSource.set(undefined);\n }\n });\n return Object.assign(\n derivedSource,\n SourceBranded,\n ) as unknown as ReadonlySource<State>;\n}\n","import {\n resource,\n linkedSignal,\n ResourceOptions,\n computed,\n} from '@angular/core';\nimport {\n CraftResourceRef,\n CraftResourceRefSpecificState,\n} from './util/craft-resource-ref';\n\nexport function preservedResource<T, R>(\n config: ResourceOptions<T, R>,\n): CraftResourceRef<T | undefined, R> {\n const original = resource(config);\n const originalCopy = { ...original };\n const preserved = linkedSignal({\n source: () => ({\n //@ts-expect-error originalCopy can access to isError\n value: originalCopy.isError() ? undefined : originalCopy.value(),\n status: originalCopy.status(),\n isLoading: originalCopy.isLoading(),\n }),\n computation: (current, previous) => {\n if (current.isLoading) {\n if (previous) {\n return previous.value;\n } else {\n return config.defaultValue;\n }\n }\n return current.value;\n },\n debugName: 'preservedResource_preserved',\n });\n const state = computed(\n () => {\n return preserved();\n },\n {\n debugName: 'preservedResource_state',\n },\n ) as CraftResourceRefSpecificState<T | undefined, R>['safeValue'];\n\n if (config.defaultValue) {\n original.set(config.defaultValue);\n }\n return {\n value: preserved,\n hasValue: original.hasValue.bind(original),\n status: original.status,\n error: original.error,\n isLoading: original.isLoading,\n reload: original.reload.bind(original),\n destroy: original.destroy.bind(original),\n update: original.update.bind(original),\n set: original.set.bind(original),\n asReadonly: original.asReadonly.bind(original),\n safeValue: state,\n paramSrc: config.params,\n state,\n } as CraftResourceRef<T | undefined, R>;\n}\n","import { computed, linkedSignal, Signal } from '@angular/core';\nimport { CraftResourceRef } from './craft-resource-ref';\n\nexport type ResourceStatus =\n | 'resolved'\n | 'error'\n | 'loading'\n | 'reloading'\n | 'idle'\n | 'local';\n\ntype FullResourceStatusSnapshot<GroupIdentifier extends string> = Map<\n GroupIdentifier,\n { status: ResourceStatus; value: unknown }\n>;\n\nexport type resourceByIdChangesTrackerResult<GroupIdentifier extends string> = {\n hasChange: Signal<boolean>;\n ids: Signal<GroupIdentifier[]>;\n resolved: Signal<GroupIdentifier[]>;\n loading: Signal<GroupIdentifier[]>;\n reloading: Signal<GroupIdentifier[]>;\n error: Signal<GroupIdentifier[]>;\n onlyValueChange: Signal<GroupIdentifier[]>;\n};\n\ntype ChangesByStatus<GroupIdentifier extends string> = {\n ids: GroupIdentifier[];\n resolved: GroupIdentifier[];\n loading: GroupIdentifier[];\n reloading: GroupIdentifier[];\n error: GroupIdentifier[];\n onlyValueChange: GroupIdentifier[];\n};\n\n/**\n * Tracks the status and value changes of resources in a ResourceByIdRef.\n * Returns an object with signals for:\n * - hasChange: true when any ID has changed status or value\n * - ids: all IDs that changed (status or value)\n * - resolved: IDs that transitioned to 'resolved' status\n * - loading: IDs that transitioned to 'loading' status\n * - reloading: IDs that transitioned to 'reloading' status\n * - error: IDs that transitioned to 'error' status\n * - onlyValueChange: IDs where only the value changed (status stayed the same)\n *\n * @param resourceByIdSignal - The signal containing the resource map to track\n * @returns An object with signals for different change types\n */\nexport function resourceByIdChangesTracker<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n>(\n resourceByIdSignal: Signal<\n Partial<Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>>\n >,\n): resourceByIdChangesTrackerResult<GroupIdentifier> {\n const changes = linkedSignal<\n FullResourceStatusSnapshot<GroupIdentifier>,\n ChangesByStatus<GroupIdentifier>\n >({\n source: () => getFullStatusSnapshot(resourceByIdSignal()),\n computation: (currentSnapshot, previous) => {\n const emptyChanges: ChangesByStatus<GroupIdentifier> = {\n ids: [],\n resolved: [],\n loading: [],\n reloading: [],\n error: [],\n onlyValueChange: [],\n };\n\n if (!previous) {\n // First read - return empty arrays\n return emptyChanges;\n }\n\n const previousSnapshot = previous.source;\n const result: ChangesByStatus<GroupIdentifier> = {\n ids: [],\n resolved: [],\n loading: [],\n reloading: [],\n error: [],\n onlyValueChange: [],\n };\n\n // Find IDs that changed status or value\n for (const [id, current] of currentSnapshot.entries()) {\n const prev = previousSnapshot.get(id);\n const statusChanged = prev?.status !== current.status;\n const valueChanged = prev?.value !== current.value;\n\n if (statusChanged || valueChanged) {\n result.ids.push(id);\n\n if (statusChanged) {\n // Add to the appropriate status array\n if (current.status === 'resolved' || current.status === 'local') {\n result.resolved.push(id);\n } else if (current.status === 'loading') {\n result.loading.push(id);\n } else if (current.status === 'reloading') {\n result.reloading.push(id);\n } else if (current.status === 'error') {\n result.error.push(id);\n }\n } else if (valueChanged) {\n // Only value changed, not status\n result.onlyValueChange.push(id);\n }\n }\n }\n\n return result;\n },\n });\n\n return {\n hasChange: computed(() => changes().ids.length > 0),\n ids: computed(() => changes().ids),\n resolved: computed(() => changes().resolved),\n loading: computed(() => changes().loading),\n reloading: computed(() => changes().reloading),\n error: computed(() => changes().error),\n onlyValueChange: computed(() => changes().onlyValueChange),\n };\n}\n\nfunction getFullStatusSnapshot<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n>(\n resources: Partial<\n Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>\n >,\n): FullResourceStatusSnapshot<GroupIdentifier> {\n const snapshot = new Map<\n GroupIdentifier,\n { status: ResourceStatus; value: unknown }\n >();\n\n for (const [id, resourceRef] of Object.entries(resources) as [\n GroupIdentifier,\n CraftResourceRef<State, ResourceParams> | undefined,\n ][]) {\n if (!resourceRef) continue;\n snapshot.set(id, {\n status: resourceRef.status(),\n value: resourceRef.hasValue() ? resourceRef.value() : undefined,\n });\n }\n\n return snapshot;\n}\n","import {\n inject,\n signal,\n ResourceOptions,\n effect,\n untracked,\n Injector,\n InjectionToken,\n WritableSignal,\n computed,\n Signal,\n linkedSignal,\n} from '@angular/core';\nimport { preservedResource } from './preserved-resource';\nimport { Prettify } from './util/util.type';\nimport { CraftResourceRef } from './util/craft-resource-ref';\nimport {\n resourceByIdChangesTracker,\n resourceByIdChangesTrackerResult,\n} from './util/resource-by-id-changes-tracker.util';\n\nexport type ResourceByIdHandler<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n> = {\n /**\n * Reset all the CraftResourceRef instance stored in the ResourceByIdRef\n */\n reset: () => void;\n /**\n * Reset the CraftResourceRef instance associated with the provided id\n */\n resetResource: (id: GroupIdentifier) => void;\n /**\n * Add a new CraftResourceRef instance\n */\n add: (\n // todo pass params instead of id and create the id from the params using the identifier function\n params: ResourceParams,\n options?: {\n defaultValue?: State;\n },\n ) => CraftResourceRef<State, ResourceParams>;\n /**\n * ! The added resource may not load immediately if the global params do not match the identifier function.\n * Useful at the app initialization when the resource value is retrieved from a persister for example.\n */\n addById: (\n id: GroupIdentifier,\n options?: {\n defaultParam?: ResourceParams;\n defaultValue?: State;\n paramsFromResourceById?: CraftResourceRef<unknown, unknown>;\n },\n ) => CraftResourceRef<State, ResourceParams>;\n /**\n * Set the values of multiple resources. If a resource doesn't exist, it will be created.\n */\n set: (payload: Partial<Record<GroupIdentifier, State>>) => void;\n /**\n * Update values of multiple resources without removing existing ones.\n * If a resource doesn't exist, it will be created.\n */\n update: (\n payload: (\n state: Partial<Record<GroupIdentifier, State>>,\n ) => Partial<Record<GroupIdentifier, State>>,\n ) => void;\n /**\n * Tracks the status and value changes of resources.\n * Provides signals for hasChange, ids, resolved, loading, reloading, error, and onlyValueChange.\n */\n changes: resourceByIdChangesTrackerResult<GroupIdentifier>;\n /**\n * A computed signal that returns a record of all resource states by their group identifier.\n */\n state: Signal<Partial<Record<GroupIdentifier, State>>>;\n};\n\nexport type Identifier<ResourceParams, GroupIdentifier> = (\n request: NonNullable<ResourceParams>,\n) => GroupIdentifier;\n\nexport type ResourceByIdRef<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n> = Signal<\n // expose a signal instead of a writableSignal to avoid typing conflicts\n Prettify<\n Partial<Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>>\n >\n> &\n ResourceByIdHandler<GroupIdentifier, State, ResourceParams>;\n\nexport type EqualParams<ResourceParams, GroupIdentifier extends string> =\n | 'default'\n | 'useIdentifier'\n | ((\n a: ResourceParams,\n b: ResourceParams,\n identifierFn: (params: ResourceParams) => GroupIdentifier,\n ) => boolean);\n\ntype ResourceByIdConfig<\n State,\n ResourceParams,\n GroupIdentifier extends string,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n> = Omit<ResourceOptions<State, ResourceParams>, 'params'> &\n (\n | {\n fromResourceById?: never;\n params: () => ResourceParams;\n identifier: Identifier<NoInfer<ResourceParams>, GroupIdentifier>;\n equalParams?: EqualParams<ResourceParams, GroupIdentifier>;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will kill the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n params: (\n entity: CraftResourceRef<\n NoInfer<FromObjectState>,\n NoInfer<FromObjectResourceParams>\n >,\n ) => ResourceParams;\n identifier: Identifier<NoInfer<ResourceParams>, GroupIdentifier>;\n equalParams?: EqualParams<ResourceParams, GroupIdentifier>;\n }\n );\n\nexport function resourceById<\n State,\n ResourceParams,\n GroupIdentifier extends string,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n config: ResourceByIdConfig<\n State,\n ResourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n): ResourceByIdRef<GroupIdentifier, State, ResourceParams> {\n const injector = inject(Injector);\n const { identifier, params, loader, stream, equalParams } = config;\n const fromResourceById =\n 'fromResourceById' in config ? config.fromResourceById : undefined;\n\n // maybe create a linkedSignal to enable to reset\n const resourceByGroup = signal<\n Partial<Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>>\n >({});\n\n const resourceEqualParams =\n equalParams === 'useIdentifier'\n ? (a: NonNullable<ResourceParams>, b: NonNullable<ResourceParams>) =>\n a && b && identifier(a) === identifier(b)\n : equalParams;\n\n // this effect is used to create a mapped CraftResourceRef instance\n if (!fromResourceById) {\n effect(() => {\n //@ts-expect-error TypeScript misinterpreting, params here has no parameter\n const requestValue = params();\n if (!requestValue) {\n return;\n }\n const group = identifier(requestValue);\n\n // The effect should only trigger when the request change\n const resourceByGroupValue = untracked(() => resourceByGroup());\n const groupCraftResourceRefExist = resourceByGroupValue[group];\n if (groupCraftResourceRefExist) {\n // nothing to do, the resource is already bind with the request\n return;\n }\n\n const filteredRequestByGroup = linkedSignal({\n source: params as () => ResourceParams,\n computation: (incomingRequestValue, previousGroupRequestData) => {\n if (!incomingRequestValue) {\n return incomingRequestValue;\n }\n // filter the request push a value by comparing with the current group\n if (identifier(incomingRequestValue) !== group) {\n return previousGroupRequestData?.value;\n }\n // The request push a value that concerns the current group\n return incomingRequestValue;\n },\n });\n\n //@ts-expect-error TypeScript misinterpreting\n const paramsWithEqualRule = computed(() => filteredRequestByGroup(), {\n ...(equalParams !== 'default' && { equal: resourceEqualParams }),\n });\n\n const CraftResourceRef = createDynamicResource(injector, {\n group,\n //@ts-expect-error stream and loader conflict\n resourceOptions: {\n loader,\n params: paramsWithEqualRule,\n stream,\n },\n });\n\n // attach a new instance of CraftResourceRef to the resourceByGroup\n resourceByGroup.update((state) => ({\n ...state,\n [group]: CraftResourceRef,\n }));\n });\n }\n\n const changesTracker = resourceByIdChangesTracker(resourceByGroup);\n\n const stateSignal = computed(() => {\n const resources = resourceByGroup();\n const stateRecord: Partial<Record<GroupIdentifier, State>> = {};\n for (const [key, resource] of Object.entries(resources)) {\n if (resource) {\n const craftResource = resource as CraftResourceRef<\n State,\n ResourceParams\n >;\n if (craftResource.hasValue()) {\n stateRecord[key as GroupIdentifier] = craftResource.value();\n }\n }\n }\n return stateRecord;\n });\n\n const resourcesHandler: ResourceByIdHandler<\n GroupIdentifier,\n State,\n ResourceParams\n > = {\n changes: changesTracker,\n state: stateSignal,\n reset: () => {\n Object.values(resourceByGroup()).forEach((resource) =>\n (resource as CraftResourceRef<State, ResourceParams>).destroy(),\n );\n resourceByGroup.set({});\n },\n resetResource: (id: GroupIdentifier) => {\n resourceByGroup.update((state) => {\n const newState = { ...state };\n newState[id]?.destroy();\n delete newState[id];\n return newState;\n });\n },\n set: (payload: Partial<Record<GroupIdentifier, State>>) => {\n // Remove existing keys that are not in the payload\n const currentResources = resourceByGroup();\n Object.keys(currentResources).forEach((id) => {\n if (!(id in payload)) {\n resourcesHandler.resetResource(id as GroupIdentifier);\n }\n });\n\n // Set or create resources from the payload\n Object.entries(payload).forEach(([id, value]) => {\n const existingResource = resourceByGroup()[id as GroupIdentifier];\n if (existingResource) {\n existingResource.set(value as State);\n } else {\n // If the resource doesn't exist, create it with the provided value as default\n resourcesHandler.addById(id as GroupIdentifier, {\n defaultValue: value as State,\n });\n }\n });\n },\n update: (\n payload: (\n state: Partial<Record<GroupIdentifier, State>>,\n ) => Partial<Record<GroupIdentifier, State>>,\n ) => {\n const nextState = payload(stateSignal());\n resourcesHandler.set(nextState);\n },\n add: (resourceParams, options?: { defaultValue?: State }) => {\n const group = identifier(resourceParams as any);\n if (resourceByGroup()[group]) {\n return resourceByGroup()[group] as CraftResourceRef<\n State,\n ResourceParams\n >;\n }\n\n //@ts-expect-error ! It does not handle the case when fromResourceById is provided\n const computedParam = computed(() => params() ?? resourceParams);\n const filteredGlobalParamsByGroup = linkedSignal({\n source: computedParam as () => ResourceParams,\n computation: (incomingParamsValue, previousGroupParamsData) => {\n if (!incomingParamsValue) {\n return incomingParamsValue;\n }\n // filter the request push a value by comparing with the current group\n if (identifier(incomingParamsValue) !== group) {\n return (\n (previousGroupParamsData?.value as ResourceParams) ??\n resourceParams\n );\n }\n // The request push a value that concerns the current group\n return incomingParamsValue;\n },\n });\n // ! without pulling the signal here, it is not possible to load multiples resources in the same cycle\n const _pull_filteredGlobalParamsByGroup = filteredGlobalParamsByGroup();\n const paramsWithEqualRule = computed(\n filteredGlobalParamsByGroup as Signal<NonNullable<ResourceParams>>,\n //@ts-expect-error TypeScript misinterpreting\n {\n ...(equalParams !== 'default' && {\n equal: resourceEqualParams,\n }),\n },\n );\n const CraftResourceRef = createDynamicResource(injector, {\n group,\n resourceOptions: {\n loader,\n params: paramsWithEqualRule,\n stream,\n defaultValue: options?.defaultValue,\n } as ResourceOptions<State, ResourceParams>,\n });\n resourceByGroup.update((state) => ({\n ...state,\n [group]: CraftResourceRef,\n }));\n return CraftResourceRef;\n },\n addById: (\n group,\n options?: {\n defaultValue?: State;\n defaultParam?: ResourceParams;\n paramsFromResourceById?: CraftResourceRef<unknown, unknown>;\n },\n ) => {\n // Check if the resource already exist\n if (resourceByGroup()[group]) {\n return resourceByGroup()[group] as CraftResourceRef<\n State,\n ResourceParams\n >;\n }\n const filteredGlobalParamsByGroup = linkedSignal({\n source: () =>\n params(\n options?.paramsFromResourceById as CraftResourceRef<\n FromObjectState,\n FromObjectResourceParams\n >,\n ),\n computation: (incomingParamsValue, previousGroupParamsData) => {\n if (!incomingParamsValue) {\n return incomingParamsValue ?? options?.defaultParam;\n }\n // filter the request push a value by comparing with the current group\n if (identifier(incomingParamsValue) !== group) {\n return (\n (previousGroupParamsData?.value as ResourceParams) ??\n options?.defaultParam\n );\n }\n // The request push a value that concerns the current group\n return incomingParamsValue;\n },\n });\n\n // ! without pulling the signal here, it is not possible to load multiples resources in the same cycle\n const _pull_filteredGlobalParamsByGroup = filteredGlobalParamsByGroup();\n const paramsWithEqualRule = computed(\n filteredGlobalParamsByGroup as Signal<NonNullable<ResourceParams>>,\n //@ts-expect-error TypeScript misinterpreting\n {\n ...(equalParams !== 'default' && {\n equal: resourceEqualParams,\n }),\n },\n );\n const CraftResourceRef = createDynamicResource(injector, {\n group,\n resourceOptions: {\n loader,\n params: paramsWithEqualRule,\n stream,\n defaultValue: options?.defaultValue,\n } as ResourceOptions<State, ResourceParams>,\n });\n resourceByGroup.update((state) => ({\n ...state,\n [group]: CraftResourceRef,\n }));\n return CraftResourceRef;\n },\n };\n\n if (!fromResourceById) {\n return Object.assign(resourceByGroup.asReadonly(), resourcesHandler);\n }\n\n effect(() => {\n const fromResourceByIdValue = fromResourceById?.();\n if (!fromResourceByIdValue) {\n return;\n }\n const resourceByGroupValue = resourceByGroup();\n Object.entries(fromResourceByIdValue).forEach(([key, resource]) => {\n const currentParams = params(\n resource as CraftResourceRef<FromObjectState, FromObjectResourceParams>,\n );\n if (!currentParams) {\n return;\n }\n\n untracked(() => {\n const group = identifier(currentParams as any);\n const existingCraftResourceRef = resourceByGroupValue[group];\n if (existingCraftResourceRef) {\n return;\n }\n resourcesHandler.addById(group, {\n paramsFromResourceById: resource as CraftResourceRef<\n FromObjectState,\n FromObjectResourceParams\n >,\n });\n });\n });\n });\n\n return Object.assign(resourceByGroup.asReadonly(), resourcesHandler);\n}\n\nconst RESOURCE_INSTANCE_TOKEN = new InjectionToken<\n CraftResourceRef<unknown, unknown>\n>(\n 'Injection token used to provide a dynamically created CraftResourceRef instance.',\n);\n\ninterface DynamicResourceConfig<T, R, GroupIdentifier extends string> {\n resourceOptions: ResourceOptions<T, R>;\n group: GroupIdentifier;\n}\n\n/**\n * It is not possible to instantiate a resource from within an effect directly:\n * NG0602: effect() cannot be called from within a reactive context.\n *\n * The workaround is to create a dynamic injection token using a factory function,\n * which instantiates the resource using the provided configuration.\n *\n * Maybe their is a better way to instantiate a resource dynamically.\n */\nfunction createDynamicResource<T, R, GroupIdentifier extends string>(\n parentInjector: Injector,\n resourceConfig: DynamicResourceConfig<T, R, GroupIdentifier>,\n) {\n const injector = Injector.create({\n providers: [\n {\n provide: RESOURCE_INSTANCE_TOKEN,\n useFactory: () => preservedResource(resourceConfig.resourceOptions),\n },\n ],\n parent: parentInjector,\n });\n\n const CraftResourceRef = injector.get(RESOURCE_INSTANCE_TOKEN);\n return CraftResourceRef as CraftResourceRef<T, R>;\n}\n","import { computed, resource, ResourceOptions, Signal } from '@angular/core';\nimport { CraftResourceRef } from './util/craft-resource-ref';\n\nexport function craftResource<Value, Params>(\n options: ResourceOptions<Value, Params>,\n): CraftResourceRef<Value, Params> {\n const resourceRef = resource(options);\n // do not use Object.assign, it will cause a cyclic dependency error\n return {\n value: resourceRef.value,\n hasValue: resourceRef.hasValue.bind(resourceRef),\n status: resourceRef.status,\n error: resourceRef.error,\n isLoading: resourceRef.isLoading,\n reload: resourceRef.reload.bind(resourceRef),\n destroy: resourceRef.destroy.bind(resourceRef),\n update: resourceRef.update.bind(resourceRef),\n set: resourceRef.set.bind(resourceRef),\n asReadonly: resourceRef.asReadonly.bind(resourceRef),\n safeValue: computed(\n () => (resourceRef.hasValue() ? resourceRef.value() : undefined),\n {\n debugName: 'craftResourceSafeValue',\n },\n ),\n paramSrc: options.params as Signal<Params>,\n state: computed(\n () => (resourceRef.hasValue() ? resourceRef.value() : undefined),\n {\n debugName: 'craftResourceState',\n },\n ),\n } as CraftResourceRef<Value, Params>;\n}\n","import {\n computed,\n isSignal,\n ResourceLoaderParams,\n ResourceOptions,\n ResourceStatus,\n ResourceStreamingLoader,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { InsertionsResourcesFactory } from './query.core';\nimport { ReadonlySource } from './util/source.type';\nimport { resourceById, ResourceByIdRef } from './resource-by-id';\nimport { isSource } from './util/util';\nimport { MergeObjects } from './util/util.type';\nimport { craftResource } from './craft-resource';\n\n// ! It looks like TS does not handle to expose the ResourceByIdHandler without erasing the () => ... part\nexport type AsyncProcessRef<\n Value,\n ArgParams,\n Params,\n Insertions,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n> = MergeObjects<\n [\n [unknown] extends [GroupIdentifier]\n ? {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n }\n : {},\n Insertions,\n IsMethod extends true\n ? {\n method: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n [unknown] extends [GroupIdentifier]\n ? {}\n : ResourceByIdRef<GroupIdentifier & string, Value, Params> & {\n _resourceById: ResourceByIdRef<\n GroupIdentifier & string,\n Value,\n Params\n >;\n /**\n * Get the associated resource by id\n *\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n *\n * return the associated resource or undefined if not existing\n */\n select: (id: GroupIdentifier) =>\n | {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n }\n | undefined;\n },\n ]\n>;\n\ntype AsyncProcessConfig<\n ResourceState,\n Params,\n ParamsArgs,\n SourceParams,\n GroupIdentifier,\n> = Omit<ResourceOptions<NoInfer<ResourceState>, Params>, 'params' | 'loader'> &\n (\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n preservePreviousValue?: () => boolean;\n }\n | {\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n preservePreviousValue?: () => boolean;\n }\n );\n\nexport type AsyncProcessOutput<\n State extends object | undefined,\n Params,\n ArgParams,\n SourceParams,\n GroupIdentifier,\n Insertions,\n> = AsyncProcessRef<\n State,\n ArgParams,\n Params,\n Insertions,\n [unknown] extends [ArgParams] ? false : true, // ! force to method to have one arg minimum, we can not compare SourceParams type, because it also infer Params\n SourceParams,\n GroupIdentifier\n>;\n\n/**\n * Creates an async method that manages asynchronous operations with automatic state tracking.\n *\n * This function creates a reactive async operation by:\n * - Managing loading, resolved, error, and idle states automatically\n * - Supporting both method-based (manual) and source-based (automatic) triggering\n * - Enabling parallel execution with identifiers\n * - Providing signals for value, status, error, and loading state\n * - Supporting streaming data with progressive updates\n * - Enabling custom insertions for extending functionality\n *\n * @remarks\n * **Trigger Patterns:**\n * - **Method-based**: Explicit `method` function returns params, called manually\n * - **Source-based**: Bound to a source using `afterRecomputation()`, triggers automatically\n *\n * **Use Cases:**\n * - **Debounced operations**: Search, validation with delay\n * - **Background tasks**: Processing without blocking UI\n * - **Polling**: Periodic data updates\n *\n * **State Management:**\n * - `idle`: Initial state, no operation started\n * - `loading`: Operation in progress\n * - `resolved`: Operation completed successfully\n * - `error`: Operation failed\n *\n * **Identifier Usage:**\n * - Without identifier: Single global state for the async method\n * - With identifier: Multiple parallel instances with independent states\n *\n * **Insertions:**\n * - Extend functionality with custom insertions\n * - Examples: persistence, caching, retry logic\n * - Insertions receive access to resource state and params\n *\n * @template AsyncProcesstate - The type of data returned by the async operation\n * @template AsyncProcessParams - The type of params passed to the loader\n * @template AsyncProcessArgsParams - The type of arguments for the method function\n * @template SourceParams - The type emitted by the source (for source-based methods)\n * @template GroupIdentifier - The type of identifier for parallel execution\n *\n * @param AsyncProcessConfig - Configuration object:\n * - `method`: Function returning params OR source for automatic triggering\n * - `loader`: Async function that performs the operation (mutually exclusive with `stream`)\n * - `stream`: Streaming loader for progressive updates (mutually exclusive with `loader`)\n * - `identifier`: Optional function to derive unique ID for parallel execution\n *\n * @returns An async method reference with:\n * - `value`: Signal containing the result (or undefined)\n * - `status`: Signal with current state ('idle' | 'loading' | 'resolved' | 'error')\n * - `error`: Signal containing error (or undefined)\n * - `isLoading`: Signal for loading state\n * - `hasValue()`: Function to check if value exists\n * - `method`: (method-based only) Function to trigger the operation\n * - `source`: (source-based only) Readonly source for automatic triggering\n * - `select(id)`: (with identifier) Access individual instance by ID\n *\n * @example\n * Basic method-based async method\n * ```ts\n * const delay = asyncProcess({\n * method: (delay: number) => delay,\n * loader: async ({ params }) => {\n * await new Promise(resolve => setTimeout(resolve, 500)); // Simulate delay\n * return 'done';\n * },\n * });\n *\n * // Trigger manually\n * delay.method(500);\n *\n * // Track state\n * console.log(delay.status()); // 'loading'\n * console.log(delay.isLoading()); // true\n *\n * // After completion\n * console.log(delay.status()); // 'resolved'\n * console.log(delay.value()); // 'done'\n * console.log(delay.hasValue()); // true\n * ```\n *\n * @example\n * Source-based async method for automatic execution\n * ```ts\n * const delaySource = source<number>();\n *\n * const delay = asyncProcess({\n * method: afterRecomputation(delaySource, (term) => term),\n * loader: async ({ params }) => {\n * // Debounce at source level\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done';\n * },\n * });\n *\n * // Triggers automatically when source emits\n * delaySource.set(500);\n * // -> delay executes automatically\n *\n * // No manual method, only source\n * console.log(delay.source); // ReadonlySource<number>\n * console.log(delay.status()); // Current state\n * ```\n *\n * @example\n * Async method with identifier for parallel operations\n * ```ts\n * const delayById = asyncProcess({\n * method: (id: string) => id,\n * identifier: (id) => id,\n * loader: async () => {\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done'; // Simulate delay\n * },\n * });\n *\n * delayById.method('id1');\n * delayById.method('id2');\n * delayById.method('id3');\n *\n * // Access individual states\n * const delay1 = delayById.select('id1');\n * console.log(delay1?.status()); // 'loading' or 'resolved'\n * console.log(delay1?.value()); // 'done'\n *\n * const delay2 = delayById.select('id2');\n * console.log(delay2?.status()); // Independent state\n * ```\n *\n * @example\n * Calling async js native API\n * ```ts\n * const shareContent = asyncProcess({\n * method: (payload: { title: string, url: string }) => payload,\n * loader: async ({ params }) => {\n * return navigator.share(params);\n * },\n * }, ({resource}) => ({isMenuOpen: computed(() => resource.status() === 'loading')} ));\n *\n * // Trigger shareContent\n * shareContent.method({ title: 'Hello AI!', url: 'https://example.com' });\n * shareContent.isMenuOpen(); // true while loading\n *\n * ```\n */\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n ...insertions: any[]\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n> {\n const AsyncProcessResourceParamsFnSignal = signal<\n AsyncProcessParams | undefined\n >(undefined);\n\n const isConnectedToSource = isSource(AsyncProcessConfig.method);\n\n const isUsingIdentifier = 'identifier' in AsyncProcessConfig;\n\n const resourceParamsSrc = isConnectedToSource\n ? AsyncProcessConfig.method\n : AsyncProcessResourceParamsFnSignal;\n\n const resourceTarget = isUsingIdentifier\n ? resourceById<\n AsyncProcesstate,\n AsyncProcessParams,\n GroupIdentifier & string,\n string,\n unknown,\n unknown\n >({\n ...AsyncProcessConfig,\n params: resourceParamsSrc,\n identifier: AsyncProcessConfig.identifier,\n } as any)\n : craftResource<AsyncProcesstate, AsyncProcessParams>({\n ...AsyncProcessConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>);\n\n return Object.assign(\n resourceTarget,\n // byId is used to helps TS to correctly infer the resourceByGroup\n isUsingIdentifier\n ? {\n /**\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n */\n _resourceById: resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n AsyncProcesstate,\n AsyncProcessParams\n >,\n select: (id: GroupIdentifier) => {\n return computed(() => {\n const list = (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n AsyncProcesstate,\n AsyncProcessParams\n >\n )();\n //@ts-expect-error GroupIdentifier & string is not recognized correctly\n return list[id];\n })();\n },\n }\n : {},\n {\n method: isSignal(AsyncProcessConfig.method)\n ? undefined\n : (arg: AsyncProcessArgsParams) => {\n const result = AsyncProcessConfig.method(arg);\n if (isUsingIdentifier) {\n const id = AsyncProcessConfig.identifier?.(arg as any);\n (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n AsyncProcesstate,\n AsyncProcessParams\n >\n ).addById(id as GroupIdentifier & string);\n }\n AsyncProcessResourceParamsFnSignal.set(\n result as AsyncProcessParams,\n );\n return result;\n },\n },\n (\n insertions as InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n {}\n >[]\n )?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n ...(isUsingIdentifier\n ? { resourceById: resourceTarget }\n : { resource: resourceTarget }),\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n NoInfer<AsyncProcessParams>\n >,\n insertions: acc as {},\n state: resourceTarget.state,\n set: resourceTarget.set,\n update: resourceTarget.update,\n } as any),\n };\n },\n {} as Record<string, unknown>,\n ),\n ) as unknown as AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n >;\n}\n","import { linkedSignal, Signal, ValueEqualityFn } from '@angular/core';\nimport { ReadonlySource } from './util/source.type';\nimport { SignalSource } from './signal-source';\nimport { SourceBranded } from './util/util';\n\n/**\n * Creates a derived readonly source that transforms values from an origin source using a computation function.\n *\n * This function enables reactive transformations of source emissions by:\n * - Computing new values whenever the origin source emits\n * - Maintaining source semantics (emits only when explicitly set, not on first read)\n * - Supporting custom equality comparisons for memoization\n * - Providing both standard and value-preserving listeners\n * - Creating composable source pipelines\n *\n * @remarks\n * **Emission Behavior:**\n * - Only emits when the origin source emits (explicit set/update)\n * - First read returns `undefined` by default (maintains source semantics)\n * - Use `preserveLastValue` variant to get computed value on first read\n *\n * **Use Cases:**\n * - **Data transformation**: Convert source payloads to different shapes\n * - **Filtering**: Extract specific fields from complex source data\n * - **Formatting**: Apply formatting logic to source values\n * - **Type narrowing**: Cast or validate source data types\n * - **Composition**: Chain multiple source transformations\n * - **Business logic**: Apply domain-specific computations\n *\n * **Source vs Signal:**\n * - Sources emit only on explicit events (set/update calls)\n * - Signals recompute on every access when dependencies change\n * - computedSource maintains source lazy behavior\n *\n * **Equality Comparison:**\n * - Default: Uses Angular's default equality check\n * - Custom: Provide `equal` option for custom comparison\n * - Prevents unnecessary emissions when computed value hasn't changed\n *\n * @template SourceState - The type of values emitted by the origin source\n * @template ComputedValue - The type of values produced by the computation\n *\n * @param signalOrigin - The source or readonly source to derive from.\n * Values emitted by this source are passed to the computation function.\n *\n * @param computedFn - Function that transforms source values to computed values.\n * Called each time the origin source emits.\n *\n * @param options - Optional configuration:\n * - `equal`: Custom equality function for computed values\n * - `debugName`: Name for debugging purposes\n *\n * @returns A readonly source that emits computed values with:\n * - Standard behavior: First read returns `undefined`, subsequent reads return computed value after source emits\n * - `preserveLastValue` property: Returns computed value immediately on first read if source has emitted\n *\n * @example\n * Basic transformation of source data\n * ```ts\n * const userSource = source<{ firstName: string; lastName: string }>();\n *\n * // Compute full name from user data\n * const fullNameSource = computedSource(\n * userSource,\n * (user) => `${user.firstName} ${user.lastName}`\n * );\n *\n * // Use in async method or query\n * const greetUser = asyncProcess({\n * method: afterRecomputation(fullNameSource, (fullName) => fullName),\n * loader: async ({ params }) => {\n * return `Hello, ${params}!`;\n * },\n * });\n *\n * // Trigger chain\n * userSource.set({ firstName: 'John', lastName: 'Doe' });\n * // -> fullNameSource emits 'John Doe'\n * // -> greetUser executes with 'John Doe'\n * ```\n *\n * @example\n * Extracting specific fields from complex data\n * ```ts\n * type FormData = {\n * personal: { name: string; email: string };\n * address: { street: string; city: string };\n * preferences: { newsletter: boolean };\n * };\n *\n * const formSource = source<FormData>();\n *\n * // Extract only email for validation\n * const emailSource = computedSource(\n * formSource,\n * (form) => form.personal.email\n * );\n *\n * // Extract only address for geocoding\n * const addressSource = computedSource(\n * formSource,\n * (form) => form.address\n * );\n *\n * // Use extracted sources\n * const validateEmail = asyncProcess({\n * method: afterRecomputation(emailSource, (email) => email),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/validate-email', {\n * method: 'POST',\n * body: JSON.stringify({ email: params }),\n * });\n * return response.json();\n * },\n * });\n *\n * // Update form triggers both validations\n * formSource.set({\n * personal: { name: 'John', email: 'john@example.com' },\n * address: { street: '123 Main St', city: 'NYC' },\n * preferences: { newsletter: true },\n * });\n * ```\n *\n * @example\n * Chaining computed sources for multi-step transformation\n * ```ts\n * const inputSource = source<string>();\n *\n * // Step 1: Trim and lowercase\n * const normalizedSource = computedSource(\n * inputSource,\n * (input) => input.trim().toLowerCase()\n * );\n *\n * // Step 2: Extract search terms\n * const searchTermsSource = computedSource(\n * normalizedSource,\n * (normalized) => normalized.split(' ').filter(term => term.length > 0)\n * );\n *\n * // Step 3: Create search query\n * const searchQuerySource = computedSource(\n * searchTermsSource,\n * (terms) => ({ terms, operator: 'AND' as const })\n * );\n *\n * // Final async method uses fully transformed data\n * const search = asyncProcess({\n * method: afterRecomputation(searchQuerySource, (query) => query),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/search', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * // Single input triggers entire chain\n * inputSource.set(' Angular Signals ');\n * // -> normalizedSource emits 'angular signals'\n * // -> searchTermsSource emits ['angular', 'signals']\n * // -> searchQuerySource emits { terms: ['angular', 'signals'], operator: 'AND' }\n * // -> search executes\n * ```\n *\n * @example\n * Custom equality comparison\n * ```ts\n * type SearchParams = { query: string; timestamp: number };\n *\n * const searchSource = source<SearchParams>();\n *\n * // Only emit when query changes, ignore timestamp\n * const queryOnlySource = computedSource(\n * searchSource,\n * (params) => params.query,\n * {\n * equal: (a, b) => a === b, // Compare strings\n * }\n * );\n *\n * // Update with same query but different timestamp\n * searchSource.set({ query: 'test', timestamp: Date.now() });\n * // -> queryOnlySource emits 'test'\n *\n * searchSource.set({ query: 'test', timestamp: Date.now() });\n * // -> queryOnlySource does NOT emit (same query)\n *\n * searchSource.set({ query: 'new', timestamp: Date.now() });\n * // -> queryOnlySource emits 'new'\n * ```\n *\n * @example\n * Type narrowing and validation\n * ```ts\n * type ApiResponse =\n * | { type: 'success'; data: unknown }\n * | { type: 'error'; message: string };\n *\n * const responseSource = source<ApiResponse>();\n *\n * // Extract only successful data\n * const successDataSource = computedSource(\n * responseSource,\n * (response) => {\n * if (response.type === 'success') {\n * return response.data;\n * }\n * return null;\n * }\n * );\n *\n * // Extract only errors\n * const errorSource = computedSource(\n * responseSource,\n * (response) => {\n * if (response.type === 'error') {\n * return response.message;\n * }\n * return null;\n * }\n * );\n *\n * // Handle success and errors separately\n * const Processuccess = asyncProcess({\n * method: afterRecomputation(successDataSource, (data) => data),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * // Process successful data\n * return processData(params);\n * },\n * });\n *\n * const logError = asyncProcess({\n * method: afterRecomputation(errorSource, (error) => error),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * // Log error\n * await logToService(params);\n * return { logged: true };\n * },\n * });\n * ```\n *\n * @example\n * Formatting and presentation logic\n * ```ts\n * type Price = { amount: number; currency: string };\n *\n * const priceSource = source<Price>();\n *\n * // Format price for display\n * const formattedPriceSource = computedSource(\n * priceSource,\n * (price) => {\n * const formatter = new Intl.NumberFormat('en-US', {\n * style: 'currency',\n * currency: price.currency,\n * });\n * return formatter.format(price.amount);\n * }\n * );\n *\n * // Use formatted value in UI updates\n * const updatePriceDisplay = asyncProcess({\n * method: afterRecomputation(formattedPriceSource, (formatted) => formatted),\n * loader: async ({ params }) => {\n * // Update analytics or external service\n * await trackPriceView(params);\n * return { displayed: params };\n * },\n * });\n *\n * priceSource.set({ amount: 1234.56, currency: 'USD' });\n * // -> formattedPriceSource emits '$1,234.56'\n * ```\n *\n * @example\n * Using preserveLastValue for immediate computed access\n * ```ts\n * const counterSource = source<number>();\n *\n * const doubledSource = computedSource(\n * counterSource,\n * (count) => count * 2\n * );\n *\n * // Standard behavior\n * console.log(doubledSource()); // undefined (no emission yet)\n *\n * counterSource.set(5);\n * console.log(doubledSource()); // 10\n *\n * // Using preserveLastValue\n * const immediateDoubled = doubledSource.preserveLastValue;\n * console.log(immediateDoubled()); // 10 (gets last computed value immediately)\n * ```\n */\nexport function computedSource<SourceState, ComputedValue>(\n signalOrigin: SignalSource<SourceState> | ReadonlySource<SourceState>,\n computedFn: (sourceValue: NoInfer<SourceState>) => ComputedValue,\n options?: {\n equal?: ValueEqualityFn<NoInfer<ComputedValue> | undefined>;\n debugName?: string;\n },\n): ReadonlySource<ComputedValue> {\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<SourceState, ComputedValue | undefined>({\n source: signalOrigin as Signal<SourceState>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n\n return computedFn(currentSourceState);\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n },\n SourceBranded,\n ) as ReadonlySource<any>;\n}\n","// signal-proxy.ts\n// Purpose: Signal proxy that exposes read signals per property + write helpers for the underlying source signal.\n\nimport { Signal, signal, computed, isSignal } from '@angular/core';\nimport { MergeObject } from './util/types/util.type';\n\ntype AnyRecord = Record<PropertyKey, unknown>;\n\nexport type SignalWrapperParams<T extends object> = {\n readonly [K in keyof T]: T[K] extends Signal<infer U>\n ? Signal<U>\n : Signal<T[K]>;\n};\n\nexport type SignalProxy<\n T extends object,\n Public extends boolean = false\n> = MergeObject<\n {\n // For each property, you read it as a Signal of its final value (signals unwrapped).\n readonly [K in keyof T]: T[K] extends Signal<infer U>\n ? Signal<U>\n : Signal<T[K]>;\n },\n Public extends true\n ? {\n /** Readonly access to the whole object as a Signal<T> */\n readonly $raw: Signal<T>;\n\n /** Replace the whole object */\n $set(next: SignalWrapperParams<T>): void;\n\n /** Update the object with partial values */\n $patch(partial: Partial<SignalWrapperParams<T>>): void;\n\n /** Get the raw property (Signal or plain value) from the current object */\n $ref<K extends keyof T>(key: K): T[K];\n }\n : {}\n>;\n\nexport function createSignalProxy<T extends AnyRecord>(\n src: T | Signal<T>\n): SignalProxy<T, true> {\n const state: Signal<T> = isSignal(src) ? src : signal(src as T);\n\n // Cache property computed signals for referential stability\n const cache = new Map<PropertyKey, Signal<unknown>>();\n\n const api = {\n $raw: state,\n $set(next: T) {\n // Replace whole object\n if ((state as any).set) {\n (state as any).set(next);\n } else {\n (state as any)(next);\n }\n },\n $patch(partial: Partial<T>) {\n // Merge partial with current state\n const current = state();\n const updated = { ...current, ...partial };\n if ((state as any).set) {\n (state as any).set(updated);\n } else {\n (state as any)(updated);\n }\n },\n $ref<K extends keyof T>(key: K): T[K] {\n return (state() as any)[key];\n },\n };\n\n const handler: ProxyHandler<object> = {\n get(_target, prop: PropertyKey) {\n // Expose write API and $raw directly\n if (prop in api) return (api as any)[prop];\n\n if (\n prop === 'toJSON' ||\n prop === 'valueOf' ||\n prop === Symbol.toStringTag\n ) {\n return (state() as any)[prop];\n }\n\n if (cache.has(prop)) return cache.get(prop);\n\n // Computed read signal for property, unwrapping nested signals\n const s = computed(() => {\n const current = (state() as any)[prop];\n return isSignal(current) ? current() : current;\n });\n\n cache.set(prop, s);\n return s;\n },\n\n ownKeys() {\n return Reflect.ownKeys(state() as object);\n },\n has(_t, prop) {\n return prop in api || prop in (state() as object);\n },\n\n getOwnPropertyDescriptor(_t, prop) {\n if (prop in api) {\n return {\n configurable: true,\n enumerable: false,\n writable: false,\n value: (api as any)[prop],\n };\n }\n return {\n configurable: true,\n enumerable: true,\n writable: false,\n value: (this as any).get?.({}, prop),\n };\n },\n };\n\n return new Proxy({}, handler) as SignalProxy<T, true>;\n}\n","import { Prettify } from './util/util.type';\nimport {\n MergeObject,\n MergeObjects,\n UnionToTuple,\n} from './util/types/util.type';\nimport {\n assertInInjectionContext,\n DestroyRef,\n effect,\n EventEmitter,\n inject,\n InjectionToken,\n Injector,\n isSignal,\n Provider,\n signal,\n untracked,\n} from '@angular/core';\nimport { createSignalProxy, SignalProxy } from './signal-proxy';\nimport {\n ExcludeCommonKeys,\n HasKeys,\n RemoveIndexSignature,\n ReplaceStoreConfigToken,\n ToConnectableMethodFromInject,\n} from './util/util.type';\n\n//todo craft inouts should not accepts other params\n// todo filter private fields and methods ?\n\n// ! when adding standalone outputs make sure to assign like this: const c = Object.assign(() => true, {a: 5}) (function first)\n\n// todo find a way to simplify that, props exposed everywhere, _props only in stores and __props only in current store ?\n// todo doc about cloudProxy (it store all standalones methods automatically)\nexport type ContextConstraints = {\n props: {};\n methods: Record<string, Function>; //? (editable in injectCraft/craftCraft)\n _inputs: {}; //? (editable in injectCraft/craftCraft)\n _injections: {};\n _queryParams: {};\n _sources: {}; //? (editable in injectCraft/craftCraft)\n _mutation: {};\n _query: {};\n _AsyncProcess: {};\n _cloudProxy: {}; // A proxy that is used to share data between the injectable context and standalone outputs functions, composed store merge this proxy values\n _dependencies: {}; // todo implements composition alias and implements it\n _error: {};\n};\n\n// ! do not expose it\ntype _EmptyContext = {\n props: {};\n methods: Record<string, Function>;\n _inputs: {};\n _queryParams: {};\n _sources: {};\n _injections: {};\n _AsyncProcess: {};\n _mutation: {};\n _query: {};\n _cloudProxy: {};\n _dependencies: {};\n _error: {};\n};\n\nexport const EmptyContext = {\n props: {},\n methods: {},\n _inputs: {},\n _queryParams: {},\n _sources: {},\n _injections: {},\n _AsyncProcess: {},\n _mutation: {},\n _query: {},\n _cloudProxy: {},\n _dependencies: {},\n _error: {},\n};\n\nexport type EmptyContext = typeof EmptyContext;\n\nexport function contract<Implement>() {\n return {} as Implement;\n}\n\ntype EmptyStandaloneContext = {};\n\nexport function partialContext(\n context: Partial<ContextConstraints>,\n): ContextConstraints {\n return {\n props: context.props ?? {},\n methods: context.methods ?? {},\n _inputs: context._inputs ?? {},\n _injections: context._injections ?? {},\n _queryParams: context._queryParams ?? {},\n _sources: context._sources ?? {},\n _AsyncProcess: context._AsyncProcess ?? {},\n _mutation: context._mutation ?? {},\n _query: context._query ?? {},\n _cloudProxy: context._cloudProxy ?? {},\n _dependencies: context._dependencies ?? {},\n _error: context._error ?? {},\n };\n}\n\nexport type PartialContext<Context extends Partial<ContextConstraints>> = {\n props: [unknown] extends Context['props'] ? {} : Context['props'];\n methods: [unknown] extends Context['methods'] ? {} : Context['methods'];\n _inputs: [unknown] extends Context['_inputs'] ? {} : Context['_inputs'];\n _injections: [unknown] extends Context['_injections']\n ? {}\n : Context['_injections'];\n _queryParams: [unknown] extends Context['_queryParams']\n ? {}\n : Context['_queryParams'];\n _sources: [unknown] extends Context['_sources'] ? {} : Context['_sources'];\n _AsyncProcess: [unknown] extends Context['_AsyncProcess']\n ? {}\n : Context['_AsyncProcess'];\n _mutation: [unknown] extends Context['_mutation'] ? {} : Context['_mutation'];\n _query: [unknown] extends Context['_query'] ? {} : Context['_query'];\n _cloudProxy: [unknown] extends Context['_cloudProxy']\n ? {}\n : Context['_cloudProxy'];\n _dependencies: [unknown] extends Context['_dependencies']\n ? {}\n : Context['_dependencies'];\n _error: [unknown] extends Context['_error'] ? {} : Context['_error'];\n};\n\nexport type CloudProxy<T> = T;\nexport type CloudProxySource = Record<string, unknown>;\n\nexport type CraftFactoryEntries<Context extends ContextConstraints> =\n Context['_inputs'] &\n Context['_injections'] &\n Context['_sources'] &\n Context['props'] &\n Context['_AsyncProcess'];\n\nexport const craftFactoryEntries = (contextData: {\n context: ContextConstraints;\n}) => ({\n ...contextData.context._inputs,\n ...contextData.context._injections,\n ...contextData.context._sources,\n ...contextData.context.props,\n ...contextData.context._AsyncProcess,\n ...contextData.context._mutation,\n});\n\nexport type ContextInput<Context extends ContextConstraints> = {\n context: Context;\n};\n\n/**\n * ! Do not use it to generate the output of utilities like (craftQuery, craftMutation, etc..),\n * ! the context is not correctly inferred (use CraftFactoryUtility instead)\n */\n//todo _cloud should extends stadalone outputs _cloud\nexport type CraftFactory<\n Context extends ContextConstraints[],\n StoreConfig,\n CraftActionOutputs extends ContextConstraints,\n StandaloneContextOutputs extends {},\n> = (\n cloudProxy: CloudProxy<MergeContexts<Context>['_cloudProxy']>,\n storeConfig: StoreConfig,\n) => (<HostStoreConfig extends StoreConfigConstraints>(\n contextData: ContextInput<MergeContexts<Context>>,\n injector: Injector,\n storeConfig: StoreConfig, // do not use HostStoreConfig\n cloudProxy: MergeContexts<Context>['_cloudProxy'],\n) => CraftActionOutputs) & {\n standaloneOutputs?: StandaloneContextOutputs;\n};\n\nexport type CraftFactoryUtility<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n CraftActionOutputs extends ContextConstraints,\n StandaloneOutputs extends {} = {},\n> = (\n cloudProxy: CloudProxySource,\n storeConfig: StoreConfig,\n) => (<HostStoreConfig extends StoreConfigConstraints>(\n contextData: ContextInput<Context>,\n injector: Injector,\n storeConfig: HostStoreConfig,\n cloudProxy: Context['_cloudProxy'],\n) => CraftActionOutputs) & {\n standaloneOutputs?: StandaloneOutputs;\n};\nexport const EXTERNALLY_PROVIDED = 'EXTERNALLY_PROVIDED' as const;\n\ntype EnableInputsToBeExternallyProvided<Inputs, Enable> = {\n [key in keyof Inputs]: Enable extends true\n ? Inputs[key] | typeof EXTERNALLY_PROVIDED\n : Inputs[key];\n};\n\ntype IsNotFeature<ProvidedIn extends ProvidedInOption> =\n ProvidedIn extends 'feature' ? false : true;\n\ntype IsScoped<ProvidedIn extends ProvidedInOption> = ProvidedIn extends 'scoped'\n ? true\n : false;\n\ntype ReplaceStandaloneStoreToken<\n StandaloneOutputs extends StandaloneOutputsConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = {\n [K in keyof StandaloneOutputs as ReplaceStoreConfigToken<\n K & string,\n StoreConfig\n >]: StandaloneOutputs[K];\n};\ntype InjectCraftOutput<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n MethodsConnected,\n> = {\n [key in `inject${Capitalize<StoreConfig['name']>}Craft`]: <\n Config extends MergeObjects<\n [\n HasInputs extends true\n ? {\n inputs: InputsToPlugin;\n }\n : {},\n HasMethods extends true\n ? {\n methods?: Prettify<MethodsConnected>;\n }\n : {},\n ]\n >,\n >(\n ...args: HasInputs extends true\n ? [pluggableConfig: Config]\n : [pluggableConfig?: Config]\n ) => Prettify<\n RemoveIndexSignature<\n Context['props'] &\n ExcludeCommonKeys<\n Context['methods'],\n 'methods' extends keyof Config ? Config['methods'] : {}\n >\n >\n >;\n};\n\ntype CraftCompositionOutput<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n StandaloneOutputs,\n MethodsToConnect,\n MethodsConnected extends MethodsToConnect = MethodsToConnect,\n> = {\n [key in `craft${Capitalize<StoreConfig['name']>}`]: <\n HostContext extends ContextConstraints,\n HostStoreConfig extends StoreConfigConstraints,\n Config extends MergeObjects<\n [\n HasInputs extends true\n ? {\n inputs: Partial<InputsToPlugin>;\n }\n : {},\n HasMethods extends true\n ? {\n methods?: MethodsConnected;\n }\n : {},\n ]\n >,\n >(\n pluggableConfig?: (\n configFactory: CraftFactoryEntries<HostContext>,\n ) => MergeObject<\n MergeObject<\n Config,\n Exclude<\n 'methods' extends keyof Config ? keyof Config['methods'] : never,\n keyof MethodsToConnect\n > extends infer NotKnownMethodsUnion\n ? [NotKnownMethodsUnion] extends [undefined]\n ? {}\n : {\n errorMethodMsg: `Error: You are trying to add methods that are not defined in the connected store (${StoreConfig['name']}): ${UnionToTuple<NotKnownMethodsUnion> &\n string}`;\n }\n : {}\n >,\n Exclude<\n 'inputs' extends keyof Config ? keyof Config['inputs'] : never,\n keyof InputsToPlugin\n > extends infer NotKnownInputsUnion\n ? [NotKnownInputsUnion] extends [undefined]\n ? {}\n : {\n errorInputsMsg: `Error: You are trying to add inputs that are not defined in the connected store (${StoreConfig['name']}): ${UnionToTuple<NotKnownInputsUnion> &\n string}`;\n }\n : {}\n >,\n ) => CraftFactoryUtility<\n HostContext,\n HostStoreConfig,\n {\n props: Context['props'];\n methods: ExcludeCommonKeys<\n Context['methods'],\n 'methods' extends keyof Config ? Config['methods'] : {}\n >;\n _inputs: ExcludeCommonKeys<\n Context['_inputs'],\n 'inputs' extends keyof Config ? Config['inputs'] : {}\n >;\n _queryParams: Context['_queryParams'];\n _sources: Context['_sources'];\n _injections: Context['_injections'];\n _AsyncProcess: Context['_AsyncProcess'];\n _mutation: Context['_mutation'];\n _query: Context['_query'];\n _cloudProxy: Context['_cloudProxy'];\n _dependencies: Context['_dependencies'] & {\n [key in StoreConfig['name']]: {\n storeConfig: StoreConfig;\n context: Context;\n };\n };\n _error: Context['_error'];\n },\n [StandaloneOutputs] extends [{}] ? StandaloneOutputs : {}\n >;\n};\n\ntype CraftToken<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = {\n [key in `${Capitalize<StoreConfig['name']>}Craft`]: InjectionToken<\n Prettify<RemoveIndexSignature<Context['props'] & Context['methods']>>\n >;\n};\n\ntype META_CONTEXT<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = {\n [k in `_${Uppercase<StoreConfig['name']>}_META_STORE_CONTEXT`]: {\n storeConfig: StoreConfig;\n context: Prettify<Context>;\n };\n};\n\n// ! Plugged methods are not exposed in the final store (at type level, at runtime they exists and they are not hiding)\ntype ToCraftOutputs<\n Context extends ContextConstraints[],\n StandaloneContextOutputs extends StandaloneOutputsConstraints[],\n StoreConfig extends StoreConfigConstraints,\n MergedContext extends ContextConstraints = MergeContexts<Context>,\n StandaloneOutputs = ReplaceStandaloneStoreToken<\n MergeStandaloneContexts<StandaloneContextOutputs>,\n StoreConfig\n >,\n InputsToPlugin = EnableInputsToBeExternallyProvided<\n MergedContext['_inputs'],\n IsNotFeature<StoreConfig['providedIn']>\n >,\n HasError = HasKeys<MergedContext['_error']>,\n HasInputs = keyof InputsToPlugin extends never ? false : true,\n MethodsToConnect = ToConnectableMethodFromInject<MergedContext['methods']>,\n HasMethods = keyof MethodsToConnect extends never ? false : true,\n HasContractToImplements = [unknown] extends [StoreConfig['implements']]\n ? false\n : true,\n RespectContract = HasContractToImplements extends false\n ? true\n : IsEqual<\n RemoveIndexSignature<MergedContext['props'] & MergedContext['methods']>,\n NonNullable<StoreConfig['implements']>\n >,\n> = (HasError extends false\n ? RespectContract extends true\n ? InjectCraftOutput<\n MergedContext,\n StoreConfig,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n MethodsToConnect\n > &\n CraftCompositionOutput<\n MergedContext,\n StoreConfig,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n StandaloneOutputs,\n MethodsToConnect\n > &\n CraftToken<MergedContext, StoreConfig> &\n (IsScoped<StoreConfig['providedIn']> extends true\n ? {\n [k in `provide${Capitalize<StoreConfig['name']>}Craft`]: () => Provider;\n }\n : {}) &\n StandaloneOutputs\n : {\n error: NonNullable<StoreConfig['implements']> extends Function\n ? 'Contract Implementation Error: The current contract is not called properly. Did you forget to call it as a function? i.e., contract<...>()'\n : 'Contract Implementation Error: The current contract is not respected.';\n }\n : {\n error: MergedContext['_error'];\n }) &\n META_CONTEXT<MergedContext, StoreConfig>;\n\ntype IsEqual<A, B> =\n (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2\n ? (<T>() => T extends B ? 1 : 2) extends <T>() => T extends A ? 1 : 2\n ? true\n : false\n : false;\n\ntype Diff<A, B> = {\n added: Exclude<keyof B, keyof A>;\n removed: Exclude<keyof A, keyof B>;\n changed: ChangedKeys<A, B>;\n};\n\ntype ChangedKeys<A, B> = {\n [K in keyof A & keyof B]: A[K] extends B[K]\n ? B[K] extends A[K]\n ? never\n : K\n : K;\n}[keyof A & keyof B];\n\ntype ProvidedInOption = 'root' | 'scoped' | 'feature';\nexport type StoreConfigConstraints = {\n providedIn: ProvidedInOption;\n name: string;\n implements?: unknown;\n};\n\ntype MergeContexts<C extends ContextConstraints[]> = C extends [\n infer First,\n ...infer Rest,\n]\n ? First extends ContextConstraints\n ? Rest extends ContextConstraints[]\n ? MergeTwoContexts<First, MergeContexts<Rest>>\n : First\n : never\n : _EmptyContext;\n\ntype MergeStandaloneContexts<C extends StandaloneOutputsConstraints[]> =\n C extends [infer First, ...infer Rest]\n ? First extends StandaloneOutputsConstraints\n ? Rest extends StandaloneOutputsConstraints[]\n ? First & MergeStandaloneContexts<Rest>\n : First\n : never\n : _EmptyContext;\n\nexport type MergeTwoContexts<\n A extends ContextConstraints,\n B extends ContextConstraints,\n> = {\n methods: A['methods'] & B['methods'];\n props: A['props'] & B['props'];\n _inputs: A['_inputs'] & B['_inputs'];\n _injections: A['_injections'] & B['_injections'];\n _mutation: A['_mutation'] & B['_mutation'];\n _query: A['_query'] & B['_query'];\n _queryParams: A['_queryParams'] & B['_queryParams'];\n _sources: A['_sources'] & B['_sources'];\n _AsyncProcess: A['_AsyncProcess'] & B['_AsyncProcess'];\n _cloudProxy: A['_cloudProxy'] & B['_cloudProxy'];\n _dependencies: A['_dependencies'] & B['_dependencies'];\n _error: A['_error'] & B['_error'];\n};\n\ntype StandaloneOutputsConstraints = {};\n\n/**\n * Creates a type-safe, composable state management store with Angular dependency injection.\n *\n * This is the core function for building craft stores. It enables:\n * - **Type-safe composition**: Chain multiple craft utilities (craftState, craftQuery, craftMutation, etc.)\n * - **Dependency injection**: Choose between root-level or feature-level provision\n * - **Smart naming**: Auto-generates injection and composition functions based on store name\n * - **Store composition**: Connect stores together via craftX functions with input/method binding\n * - **Standalone methods**: Export methods that can be called outside injection context\n * - **Contract enforcement**: Optional type contracts for store implementation\n * - **Error detection**: Type-level errors for configuration mistakes\n *\n * @remarks\n * **Naming Convention:**\n * Based on the `options.name` parameter, craft automatically generates:\n * - **Injection function**: `inject{Name}Craft()` - Injects the store instance\n * - **Composition function**: `craft{Name}(config?)` - Composes this store into another\n * - **Injection token**: `{Name}Craft` - Angular injection token for the store\n * - **Metadata**: `_{UPPERCASE_NAME}_META_STORE_CONTEXT` - Type metadata for the store\n *\n * Examples:\n * - `name: 'counter'` → `injectCounterCraft()`, `craftCounter()`\n * - `name: 'userAuth'` → `injectUserAuthCraft()`, `craftUserAuth()`\n * - `name: 'dataPagination'` → `injectDataPaginationCraft()`, `craftDataPagination()`\n *\n * **ProvidedIn Strategy:**\n * The `providedIn` option controls how Angular provides the store:\n *\n * - **`'root'`** (Global singleton):\n * - Single instance shared across the entire application\n * - Survives route changes and component destruction\n * - Ideal for: global state, authentication, app configuration\n * - When composed into other stores, the same instance is reused\n *\n * - **`'feature'`** (Scoped instances):\n * - New instance created per injection context\n * - Does not survive outside its injection scope\n * - Ideal for: component-specific state, route-scoped data, isolated features\n * - When composed into other stores, each host gets its own instance\n *\n * **Store Composition:**\n * Use the generated `craft{Name}()` function to compose one store into another:\n * - Access another store's state, methods, and capabilities\n * - Bind inputs from host store to composed store\n * - Connect host methods to composed store sources\n * - Unbound inputs/methods are automatically propagated to the host\n * - Type-safe with error detection for invalid bindings\n *\n * **Injection with Input/Method Binding:**\n * The `inject{Name}Craft()` function accepts a configuration object to:\n * - **Bind inputs**: Pass signals or values to store inputs\n * - **Connect methods to sources**: Replace methods with source emissions\n * - Enable dynamic configuration at injection time\n * - Reduce boilerplate when the store is used\n *\n * **Error Detection:**\n * The type system provides compile-time errors for:\n * - **`errorMethodMsg`**: When connecting methods that don't exist in the composed store\n * - **`errorInputsMsg`**: When binding inputs that aren't defined in the composed store\n * - **Contract violations**: When the store doesn't satisfy its `implements` contract\n * - These errors appear as properties on the configuration object with descriptive messages\n *\n * **Standalone Methods:**\n * Craft utilities (craftSources, craftMutations, etc.) can expose standalone methods:\n * - These are returned directly from `craft()` and can be destructured\n * - Can be called outside Angular's injection context\n * - Useful for event handlers, callbacks, external integrations\n * - Examples: `setReset()`, `setPaginationQueryParams()`\n *\n * @template Context - The craft store context type containing all store capabilities\n * @template StoreConfig - The store configuration type with name and providedIn\n * @template ProvidedIn - The Angular injection scope ('root' or 'feature')\n * @template Name - The store name used for generating function names\n * @template ToImplementContract - Optional contract type the store must satisfy\n *\n * @param options - Store configuration object\n * @param options.name - Store name (camelCase recommended). Used to generate function names.\n * @param options.providedIn - Angular injection scope. 'root' for global singleton, 'feature' for scoped instances.\n * @param options.implements - Optional contract type. Use `contract<YourType>()` to enforce implementation.\n * @param factories - Variable number of craft utility functions (craftState, craftQuery, craftSources, etc.)\n * Each factory receives the accumulated context from previous factories.\n *\n * @returns An object containing:\n * - **`inject{Name}Craft`**: Function to inject the store with optional input/method binding\n * - **`craft{Name}`**: Function to compose this store into another store\n * - **`{Name}Craft`**: Angular injection token for manual injection\n * - **`_{UPPERCASE_NAME}_META_STORE_CONTEXT`**: Type metadata (for advanced use cases)\n * - **Standalone methods**: Any standalone outputs from craft utilities (e.g., `setReset()`)\n *\n * @example\n * Basic counter store with sources and state\n * ```ts\n * const { injectCounterCraft, setIncrement, setDecrement, setReset } = craft(\n * { name: 'counter', providedIn: 'root' },\n * craftSources({\n * increment: source<void>(),\n * decrement: source<void>(),\n * reset: source<void>(),\n * }),\n * craftState('count', ({ increment, decrement, reset }) =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * increment: afterRecomputation(increment, () => set(state() + 1)),\n * decrement: afterRecomputation(decrement, () => set(state() - 1)),\n * reset: afterRecomputation(reset, () => set(0)),\n * })\n * )\n * )\n * );\n *\n * // In a component\n * const store = injectCounterCraft();\n * console.log(store.count()); // 0\n * store.setIncrement(); // count: 1\n * store.setDecrement(); // count: 0\n * store.setReset(); // count: 0\n *\n * // Standalone methods work outside injection context\n * document.addEventListener('click', () => {\n * setIncrement(); // Works!\n * });\n * ```\n *\n * @example\n * Store with inputs for dynamic configuration\n * ```ts\n * const { injectTimerCraft } = craft(\n * { name: 'timer', providedIn: 'feature' }, // Feature-scoped\n * craftInputs({\n * initialValue: undefined as number | undefined,\n * step: undefined as number | undefined,\n * }),\n * craftSources({\n * tick: source<void>(),\n * }),\n * craftState('time', ({ initialValue, step, tick }) =>\n * state(\n * linkedSignal(() => initialValue() ?? 0),\n * ({ state, set }) => ({\n * tick: afterRecomputation(tick, () => {\n * set(state() + (step() ?? 1));\n * }),\n * })\n * )\n * )\n * );\n *\n * // Inject with input binding\n * const timer1 = injectTimerCraft({\n * inputs: {\n * initialValue: signal(100),\n * step: signal(5),\n * },\n * });\n *\n * const timer2 = injectTimerCraft({\n * inputs: {\n * initialValue: signal(0),\n * step: signal(1),\n * },\n * });\n *\n * // Each instance is independent (feature-scoped)\n * timer1.time(); // 100\n * timer2.time(); // 0\n * ```\n *\n * @example\n * Store composition with root-level singleton\n * ```ts\n * // Global authentication store\n * const { craftAuth } = craft(\n * { name: 'auth', providedIn: 'root' }, // Global singleton\n * craftState('user', () =>\n * state(\n * { id: null, name: '' },\n * ({ set }) => ({\n * login: (user: { id: number; name: string }) => set(user),\n * logout: () => set({ id: null, name: '' }),\n * })\n * )\n * )\n * );\n *\n * // Dashboard store uses auth\n * const { injectDashboardCraft } = craft(\n * { name: 'dashboard', providedIn: 'root' },\n * craftAuth(), // No config needed, uses shared instance\n * craftState('dashboardData', ({ user }) =>\n * state(\n * linkedSignal(() => `Dashboard for ${user().name}`),\n * () => ({})\n * )\n * )\n * );\n *\n * // Profile store also uses auth\n * const { injectProfileCraft } = craft(\n * { name: 'profile', providedIn: 'root' },\n * craftAuth(), // Same auth instance\n * craftState('profileData', ({ user }) =>\n * state(\n * linkedSignal(() => `Profile: ${user().name}`),\n * () => ({})\n * )\n * )\n * );\n *\n * // Both stores share the same auth instance\n * const dashboard = injectDashboardCraft();\n * const profile = injectProfileCraft();\n *\n * dashboard.userLogin({ id: 1, name: 'Alice' });\n * console.log(dashboard.user().name); // 'Alice'\n * console.log(profile.user().name); // 'Alice' (same instance!)\n * ```\n *\n * @example\n * Store composition with feature-level scoping\n * ```ts\n * // Reusable pagination store\n * const { craftPagination } = craft(\n * { name: 'pagination', providedIn: 'feature' }, // Scoped instance\n * craftInputs({\n * pageSize: undefined as number | undefined,\n * }),\n * craftState('page', ({ pageSize }) =>\n * state(\n * { current: 1, size: linkedSignal(() => pageSize() ?? 10) },\n * ({ state, set }) => ({\n * nextPage: () => set({ ...state(), current: state().current + 1 }),\n * prevPage: () => set({ ...state(), current: state().current - 1 }),\n * })\n * )\n * )\n * );\n *\n * // Users table with pagination\n * const { injectUsersTableCraft } = craft(\n * { name: 'usersTable', providedIn: 'root' },\n * craftPagination(() => ({\n * inputs: { pageSize: signal(20) },\n * })),\n * craftState('users', () => state([], () => ({})))\n * );\n *\n * // Products table with pagination\n * const { injectProductsTableCraft } = craft(\n * { name: 'productsTable', providedIn: 'root' },\n * craftPagination(() => ({\n * inputs: { pageSize: signal(50) },\n * })),\n * craftState('products', () => state([], () => ({})))\n * );\n *\n * // Each table has its own pagination instance\n * const usersTable = injectUsersTableCraft();\n * const productsTable = injectProductsTableCraft();\n *\n * usersTable.page().size; // 20\n * productsTable.page().size; // 50\n * usersTable.pageNextPage();\n * usersTable.page().current; // 2\n * productsTable.page().current; // 1 (independent!)\n * ```\n *\n * @example\n * Binding methods to sources during composition\n *\n * When composing stores, you can connect methods from a composed store to sources\n * in the host store. When a method is connected to a source:\n * - The method is automatically called when the source emits a value\n * - **The connected method is NOT exposed in the final host store**\n * - Only the source's setter method (e.g., `emitSourceName`) remains accessible\n * - This prevents redundant API surface and enforces reactive patterns\n *\n * ```ts\n * const { craftLogger } = craft(\n * { name: 'logger', providedIn: 'root' },\n * craftSources(() => ({\n * log: source$<string>(),\n * })),\n * craftState('logs', ({ log }) =>\n * state(\n * [] as string[],\n * ({ state, set }) => ({\n * addLog: afterRecomputation(log, (message) => {\n * set([...state(), message]);\n * }),\n * clear: () => set([]),\n * })\n * )\n * )\n * );\n *\n * const { injectAppCraft } = craft(\n * { name: 'app', providedIn: 'root' },\n * craftSources(() => ({\n * appError: source$<string>(),\n * })),\n * craftState('errorCount', ({ appError }) =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * onError: afterRecomputation(appError, () => set(state() + 1)),\n * })\n * )\n * ),\n * // Connect appError source to logger's clear method\n * craftLogger(({ appError }) => ({\n * methods: {\n * logsClear: appError, // When appError emits, call logsClear\n * },\n * }))\n * );\n *\n * const app = injectAppCraft();\n * app.emitLog('User logged in');\n * app.logs().length; // 1\n *\n * // Note: app.logsClear is NOT available (connected to source)\n * // Only app.emitAppError is available\n * app.emitAppError('Something went wrong');\n * // -> errorCount incremented\n * // -> logs cleared (logsClear called automatically via appError source)\n * app.logs().length; // 0\n * app.errorCount(); // 1\n * ```\n *\n * @example\n * Connecting composed store methods to host sources with query params\n * ```ts\n * const { craftGenericQueryParams } = craft(\n * { name: 'GenericQueryParams', providedIn: 'root' },\n * craftQueryParams(() => ({\n * pagination: queryParam(\n * {\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * },\n * ({ set }) => ({\n * reset: () => set({ page: 1 }),\n * goTo: (page: number) => set({ page }),\n * }),\n * ),\n * })),\n * );\n *\n * const { injectHostCraft } = craft(\n * { name: 'host', providedIn: 'root' },\n * craftSources(() => ({\n * reset: source$<void>(),\n * goTo: source$<number>(),\n * })),\n * craftGenericQueryParams(({ reset, goTo }) => ({\n * methods: {\n * paginationReset: reset, // Connect to reset source\n * paginationGoTo: goTo, // Connect to goTo source\n * },\n * })),\n * );\n *\n * const host = injectHostCraft();\n *\n * // ❌ These methods are NOT exposed (connected to sources):\n * // host.paginationReset\n * // host.paginationGoTo\n *\n * // ✅ Only source emitters are available:\n * host.emitGoTo(5); // Triggers paginationGoTo(5)\n * host.pagination(); // { page: 5 }\n * host.emitReset(); // Triggers paginationReset()\n * host.pagination(); // { page: 1 }\n * ```\n *\n * @example\n * Input/method binding with EXTERNALLY_PROVIDED\n * ```ts\n * const { craftTheme } = craft(\n * { name: 'theme', providedIn: 'root' },\n * craftInputs({\n * initialTheme: undefined as 'light' | 'dark' | undefined,\n * }),\n * craftState('theme', ({ initialTheme }) =>\n * state(\n * linkedSignal(() => initialTheme() ?? 'light'),\n * ({ set }) => ({\n * setTheme: (theme: 'light' | 'dark') => set(theme),\n * })\n * )\n * )\n * );\n *\n * // Host store binds the input\n * const { injectAppCraft } = craft(\n * { name: 'app', providedIn: 'root' },\n * craftState('appTheme', () => state('dark' as 'light' | 'dark', () => ({}))),\n * craftTheme(({ appTheme }) => ({\n * inputs: {\n * initialTheme: appTheme, // Bind input\n * },\n * }))\n * );\n *\n * // Another host provides the input externally\n * const { craftOtherApp } = craft(\n * { name: 'otherApp', providedIn: 'root' },\n * // Input is not bound here, marked as EXTERNALLY_PROVIDED\n * craftTheme(() => ({\n * inputs: {\n * initialTheme: 'EXTERNALLY_PROVIDED',\n * },\n * }))\n * );\n *\n * // When composing otherApp, initialTheme must be provided\n * const { injectFinalCraft } = craft(\n * { name: 'final', providedIn: 'root' },\n * craftOtherApp(() => ({\n * inputs: {\n * initialTheme: signal('light'), // Must provide this\n * },\n * }))\n * );\n * ```\n *\n * @example\n * Query and mutation with automatic reactivity\n * ```ts\n * const { injectTodosCraft } = craft(\n * { name: 'todos', providedIn: 'root' },\n * craftQuery('todoList', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json();\n * },\n * })\n * ),\n * craftMutations(() => ({\n * addTodo: mutation({\n * method: (text: string) => ({ text }),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/todos', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * onSuccess: ({ helpers }) => {\n * // Invalidate query on success\n * helpers.invalidateQueries(['todoList']);\n * },\n * }),\n * }))\n * );\n *\n * const todos = injectTodosCraft();\n * todos.mutateAddTodo('Buy milk'); // Mutation\n * // -> todoList query auto-refreshes after mutation succeeds\n * ```\n *\n * @example\n * Query params for URL synchronization\n * ```ts\n * const { injectSearchCraft, setSearchQueryParams } = craft(\n * { name: 'search', providedIn: 'root' },\n * craftQueryParam('search', () =>\n * queryParam({\n * state: {\n * query: {\n * fallbackValue: '',\n * parse: (value) => value,\n * serialize: (value) => value,\n * },\n * page: {\n * fallbackValue: 1,\n * parse: (value) => parseInt(value, 10),\n * serialize: (value) => String(value),\n * },\n * },\n * })\n * ),\n * craftQuery('results', ({ searchQuery, searchPage }) =>\n * query({\n * params: linkedSignal(() => ({\n * q: searchQuery(),\n * page: searchPage(),\n * })),\n * loader: async ({ params }) => {\n * const response = await fetch(\n * `/api/search?q=${params.q}&page=${params.page}`\n * );\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const search = injectSearchCraft();\n *\n * // Change query params (syncs to URL)\n * setSearchQueryParams({ query: 'angular', page: 2 });\n * // -> URL updates to ?query=angular&page=2\n * // -> results query auto-refreshes with new params\n * ```\n *\n * @example\n * Async methods for side effects\n * ```ts\n * const { injectNotificationsCraft } = craft(\n * { name: 'notifications', providedIn: 'root' },\n * craftState('messages', () =>\n * state(\n * [] as string[],\n * ({ state, set }) => ({\n * addMessage: (msg: string) => set([...state(), msg]),\n * clear: () => set([]),\n * })\n * )\n * ),\n * craftAsyncProcesses(() => ({\n * showNotification: asyncProcess({\n * method: (message: string, duration: number) => ({ message, duration }),\n * loader: async ({ params, helpers }) => {\n * helpers.methods.messagesAddMessage(params.message);\n * await new Promise((resolve) => setTimeout(resolve, params.duration));\n * // Auto-remove after duration\n * const current = helpers.props.messages();\n * helpers.methods.messagesClear();\n * return 'done';\n * },\n * }),\n * }))\n * );\n *\n * const notifications = injectNotificationsCraft();\n * notifications.showNotificationExecute('Hello!', 3000);\n * // Message appears, then disappears after 3 seconds\n * ```\n *\n * @example\n * Contract enforcement for type safety\n * ```ts\n * type CounterContract = {\n * count: Signal<number>;\n * increment: () => void;\n * decrement: () => void;\n * };\n *\n * // This store satisfies the contract\n * const { injectCounterCraft } = craft(\n * {\n * name: 'counter',\n * providedIn: 'root',\n * implements: contract<CounterContract>(),\n * },\n * craftState('count', () =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * increment: () => set(state() + 1),\n * decrement: () => set(state() - 1),\n * })\n * )\n * )\n * );\n *\n * // This would cause a type error (missing decrement)\n * const { injectBadCounterCraft } = craft(\n * {\n * name: 'badCounter',\n * providedIn: 'root',\n * implements: contract<CounterContract>(), // Error!\n * },\n * craftState('count', () =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * increment: () => set(state() + 1),\n * // Missing decrement!\n * })\n * )\n * )\n * );\n * ```\n *\n * @example\n * Error detection for invalid composition\n * ```ts\n * const { craftLogger } = craft(\n * { name: 'logger', providedIn: 'root' },\n * craftState('logs', () =>\n * state(\n * [] as string[],\n * ({ set }) => ({\n * clear: () => set([]),\n * })\n * )\n * )\n * );\n *\n * const { injectAppCraft } = craft(\n * { name: 'app', providedIn: 'root' },\n * craftLogger(() => ({\n * methods: {\n * logsClear: signal<void>(), // OK\n * logsInvalidMethod: signal<void>(), // Type error!\n * // errorMethodMsg: \"Error: You are trying to add methods that are not\n * // defined in the connected store (logger): logsInvalidMethod\"\n * },\n * inputs: {\n * nonExistentInput: signal(5), // Type error!\n * // errorInputsMsg: \"Error: You are trying to add inputs that are not\n * // defined in the connected store (logger): nonExistentInput\"\n * },\n * }))\n * );\n * ```\n *\n * @example\n * Complex multi-store composition\n * ```ts\n * // Shared auth store\n * const { craftAuth } = craft(\n * { name: 'auth', providedIn: 'root' },\n * craftState('user', () =>\n * state({ id: null, role: 'guest' }, ({ set }) => ({\n * login: (user: { id: number; role: string }) => set(user),\n * logout: () => set({ id: null, role: 'guest' }),\n * }))\n * )\n * );\n *\n * // Pagination feature\n * const { craftPagination } = craft(\n * { name: 'pagination', providedIn: 'feature' },\n * craftInputs({ pageSize: undefined as number | undefined }),\n * craftState('page', ({ pageSize }) =>\n * state({ current: 1, size: pageSize() ?? 10 }, ({ state, set }) => ({\n * next: () => set({ ...state(), current: state().current + 1 }),\n * prev: () => set({ ...state(), current: state().current - 1 }),\n * }))\n * )\n * );\n *\n * // Admin panel combines both\n * const { injectAdminPanelCraft } = craft(\n * { name: 'adminPanel', providedIn: 'root' },\n * craftAuth(), // Shared auth\n * craftPagination(({ user }) => ({\n * // Feature pagination with dynamic pageSize based on role\n * inputs: {\n * pageSize: linkedSignal(() => (user().role === 'admin' ? 100 : 20)),\n * },\n * })),\n * craftQuery('adminData', ({ user, page }) =>\n * query({\n * params: linkedSignal(() => ({\n * userId: user().id,\n * page: page().current,\n * })),\n * loader: async ({ params }) => {\n * // Fetch data...\n * },\n * })\n * )\n * );\n *\n * const admin = injectAdminPanelCraft();\n * admin.userLogin({ id: 1, role: 'admin' });\n * admin.page().size; // 100 (admin gets larger page size)\n * admin.pageNext();\n * // -> adminData query refreshes automatically\n * ```\n */\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n outputs8 extends ContextConstraints,\n outputs9 extends ContextConstraints,\n outputs10 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n standaloneOutputs8 extends StandaloneOutputsConstraints,\n standaloneOutputs9 extends StandaloneOutputsConstraints,\n standaloneOutputs10 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n factory8: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs8,\n standaloneOutputs8\n >,\n factory9: CraftFactory<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs9,\n standaloneOutputs9\n >,\n factory10: CraftFactory<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n outputs9,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs10,\n standaloneOutputs10\n >,\n): ToCraftOutputs<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n outputs9,\n outputs10,\n ],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n standaloneOutputs8,\n standaloneOutputs9,\n standaloneOutputs10,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n outputs8 extends ContextConstraints,\n outputs9 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n standaloneOutputs8 extends StandaloneOutputsConstraints,\n standaloneOutputs9 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n factory8: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs8,\n standaloneOutputs8\n >,\n factory9: CraftFactory<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs9,\n standaloneOutputs9\n >,\n): ToCraftOutputs<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n outputs9,\n ],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n standaloneOutputs8,\n standaloneOutputs9,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n outputs8 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n standaloneOutputs8 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n factory8: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs8,\n standaloneOutputs8\n >,\n): ToCraftOutputs<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n ],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n standaloneOutputs8,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n const Name extends string,\n const ProvidedIn extends ProvidedInOption,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3],\n [standaloneOutputs1, standaloneOutputs2, standaloneOutputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n): ToCraftOutputs<\n [outputs1, outputs2],\n [standaloneOutputs1, standaloneOutputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n): ToCraftOutputs<\n [outputs1],\n [standaloneOutputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft(\n options: StoreConfigConstraints,\n ...factoriesList: CraftFactory<\n [_EmptyContext],\n {\n providedIn: ProvidedInOption;\n name: string;\n },\n ContextConstraints,\n {}\n >[]\n): ToCraftOutputs<\n _EmptyContext[],\n EmptyStandaloneContext[],\n {\n name: string;\n providedIn: ProvidedInOption;\n implements?: unknown;\n }\n> {\n const providedIn =\n options.providedIn && ['scoped', 'feature'].includes(options.providedIn)\n ? null\n : 'root';\n const storeConfig: StoreConfigConstraints = {\n providedIn: options?.providedIn,\n name: options?.name,\n implements: options?.implements,\n };\n const name = options?.name ?? '';\n const capitalizedName = name\n ? name.charAt(0).toUpperCase() + name.slice(1)\n : '';\n const injectNameCraft = `inject${capitalizedName}Craft`;\n const craftNameCraft = `craft${capitalizedName}`;\n\n const _cloudProxy = new Proxy({}, {});\n\n const extractedStandaloneOutputs = factoriesList.reduce(\n (acc, factoryWithStandalone, index) => {\n const r = factoryWithStandalone(_cloudProxy, storeConfig) ?? {};\n acc = {\n ...acc,\n ...r,\n };\n return acc;\n },\n {} as Record<string, unknown>,\n );\n\n // _cloudProxy will now have all the standalone outputs assigned to it\n Object.assign(_cloudProxy, extractedStandaloneOutputs);\n\n // used to share context, when providedIn is not root and also used with 'inject' and with 'using'\n let sharedContext: ContextConstraints | undefined = undefined;\n const pluggableInputs = createSignalProxy(signal({}));\n let inputsKeysSet: Set<string> | undefined = undefined;\n const craftFactory = () => {\n const injector = inject(Injector);\n const { propsAndMethods, context } = mergeContextAndProps({\n factoriesList,\n pluggableInputs,\n injector,\n storeConfig,\n _cloudProxy,\n });\n inputsKeysSet = new Set(\n Object.keys((context as ContextConstraints)._inputs),\n );\n sharedContext = context;\n\n return propsAndMethods;\n };\n const token = providedIn\n ? new InjectionToken(`Craft${capitalizedName}Token`, {\n providedIn,\n factory: craftFactory,\n })\n : new InjectionToken(`Craft${capitalizedName}Token`);\n const provideCraftFn = () =>\n ({\n provide: token,\n useFactory: craftFactory,\n }) satisfies Provider;\n\n const injectCraft = () => injectNameCraft;\n\n return {\n [injectNameCraft]: (entries?: {\n inputs?: Record<string, unknown>;\n methods?: Record<string, unknown>;\n implements?: unknown;\n }) => {\n assertInInjectionContext(injectCraft);\n const tokenValue = inject(token); // inject will enable to set inputsKeysSet\n const entriesInputs = entries?.inputs;\n applyEntriesInputs({\n entriesInputs,\n keysSet: inputsKeysSet,\n targetPluggableInputs: pluggableInputs,\n });\n\n // for each methods associated to a source, trigger the targeted method when the source change\n const entriesMethods = entries?.methods;\n const connectedMethodNames = new Set<string>();\n if (entriesMethods) {\n Object.entries(entriesMethods).forEach(([methodName, source]) => {\n connectedMethodNames.add(methodName);\n effect(() => {\n const newValue = (source as Function)();\n untracked(() => {\n if (newValue !== undefined) {\n (tokenValue as any)[methodName](newValue);\n }\n });\n });\n });\n }\n\n // Filter out connected methods from the returned store\n if (connectedMethodNames.size > 0) {\n const filteredStore = Object.keys(tokenValue).reduce((acc, key) => {\n if (!connectedMethodNames.has(key)) {\n acc[key] = (tokenValue as any)[key];\n }\n return acc;\n }, {} as any);\n return filteredStore;\n }\n\n return tokenValue;\n },\n [craftNameCraft]: (\n pluggableConfig?: (context: ContextConstraints) => {\n inputs?: Record<string, unknown>;\n methods?: Record<string, Function>;\n },\n ) => {\n return (\n hostCloud: CloudProxy<Record<string, unknown>>,\n storeConfig: StoreConfigConstraints,\n ) => {\n const specificCraftContextFn = (\n contextData: ContextInput<ContextConstraints>,\n injector: Injector,\n storeConfig: StoreConfigConstraints,\n _cloudProxy: CloudProxy<Record<string, unknown>>,\n ) => {\n const entries =\n pluggableConfig?.({\n ...contextData.context._inputs,\n ...contextData.context._injections,\n ...contextData.context._sources,\n ...contextData.context.props,\n } as any) ?? {};\n\n const entriesInputs = entries?.inputs;\n\n let storeContext: ContextConstraints | undefined = undefined;\n\n if (options?.providedIn !== 'root') {\n // Create a new pluggableInputs for each host to avoid sharing state\n const localPluggableInputs = createSignalProxy(signal({}));\n const { context } = mergeContextAndProps({\n factoriesList,\n pluggableInputs: localPluggableInputs,\n injector,\n storeConfig,\n _cloudProxy,\n });\n storeContext = context;\n\n // Use a local keys set and apply entries to the local pluggable inputs\n const localInputsKeysSet = new Set(\n Object.keys((storeContext as ContextConstraints)._inputs),\n );\n applyEntriesInputs({\n entriesInputs,\n keysSet: localInputsKeysSet,\n targetPluggableInputs: localPluggableInputs,\n });\n } else {\n const _getOrGenerateStore = inject(token);\n storeContext = sharedContext;\n\n inputsKeysSet = new Set(\n Object.keys((storeContext as ContextConstraints)._inputs),\n );\n applyEntriesInputs({\n entriesInputs,\n keysSet: inputsKeysSet,\n targetPluggableInputs: pluggableInputs,\n });\n }\n\n const destroyRef = inject(DestroyRef);\n\n Object.entries(entries?.methods ?? {}).forEach(\n ([methodNameToConnect, connectedSource]) => {\n if (isSignal(connectedSource)) {\n effect(() => {\n const value = connectedSource();\n console.log('value', value);\n if (!value) {\n return;\n }\n storeContext?.methods[methodNameToConnect](connectedSource());\n });\n } else if (\n 'subscribe' in connectedSource &&\n typeof connectedSource.subscribe === 'function'\n ) {\n const sub = (\n connectedSource.subscribe as EventEmitter<unknown>['subscribe']\n )((value) => storeContext?.methods[methodNameToConnect](value));\n destroyRef.onDestroy(() => sub.unsubscribe());\n }\n },\n );\n const connectedMethodNames = new Set(\n Object.keys(entries?.methods ?? {}) as string[],\n );\n const storeContextWithoutConnectedMethods = {\n ...storeContext,\n methods: Object.entries(storeContext?.methods ?? {}).reduce(\n (acc, [methodName, method]) => {\n if (connectedMethodNames.has(methodName)) {\n return acc;\n }\n acc[methodName] = method;\n\n return acc;\n },\n {} as Record<string, Function>,\n ),\n };\n\n Object.assign(hostCloud, _cloudProxy);\n\n const resultDebug = Object.assign(\n storeContextWithoutConnectedMethods as ContextConstraints,\n extractedStandaloneOutputs,\n );\n return resultDebug;\n };\n\n const craftResult = Object.assign(\n specificCraftContextFn,\n extractedStandaloneOutputs,\n );\n\n return craftResult;\n };\n },\n [`${capitalizedName}Craft`]: token,\n [`provide${capitalizedName}Craft`]: provideCraftFn,\n ...extractedStandaloneOutputs,\n } as ToCraftOutputs<\n _EmptyContext[],\n EmptyStandaloneContext[],\n {\n name: string;\n providedIn: ProvidedInOption;\n }\n >;\n}\n\nfunction applyEntriesInputs({\n entriesInputs,\n keysSet,\n targetPluggableInputs,\n}: {\n entriesInputs: Record<string, unknown> | undefined;\n keysSet: Set<string> | undefined;\n targetPluggableInputs: { $patch: (v: any) => void };\n}) {\n if (!entriesInputs) return;\n let hasInputs = false;\n const inputs = Array.from(keysSet ?? []).reduce(\n (acc, inputKey) => {\n if (inputKey in entriesInputs) {\n hasInputs = true;\n const value = (entriesInputs as any)[inputKey];\n if (value !== EXTERNALLY_PROVIDED) {\n acc[inputKey] = value;\n }\n }\n return acc;\n },\n {} as Record<string, unknown>,\n );\n if (hasInputs) {\n targetPluggableInputs.$patch(inputs as ContextConstraints['_inputs']);\n }\n}\n\nfunction mergeContextAndProps({\n factoriesList,\n pluggableInputs,\n injector,\n storeConfig,\n _cloudProxy,\n}: {\n factoriesList: CraftFactory<\n [ContextConstraints],\n StoreConfigConstraints,\n any,\n any\n >[];\n pluggableInputs: SignalProxy<{}, true>;\n injector: Injector;\n storeConfig: StoreConfigConstraints;\n _cloudProxy: CloudProxy<Record<string, unknown>>;\n}): { propsAndMethods: any; context: any } {\n return factoriesList.reduce(\n (acc, factory) => {\n const result = (\n factory as CraftFactory<\n [ContextConstraints],\n StoreConfigConstraints,\n ContextConstraints,\n StandaloneOutputsConstraints\n >\n )(_cloudProxy, storeConfig)(\n {\n context: { ...acc.context, _inputs: pluggableInputs },\n },\n injector,\n storeConfig,\n _cloudProxy,\n );\n Object.entries(result._inputs).forEach(([key, value]) => {\n const hasValue = pluggableInputs.$ref(key as never);\n if (!hasValue) {\n pluggableInputs.$patch({ [key]: value } as any);\n }\n });\n\n Object.assign(_cloudProxy, result._cloudProxy);\n return {\n context: {\n _inputs: { ...acc.context._inputs, ...result._inputs },\n _injections: {\n ...acc.context._injections,\n ...result._injections,\n },\n props: {\n ...acc.context.props,\n ...result.props,\n },\n methods: {\n ...acc.context.methods,\n ...result.methods,\n },\n _query: {\n ...acc.context._query,\n ...result._query,\n },\n _mutation: {\n ...acc.context._mutation,\n ...result._mutation,\n },\n _queryParams: {\n ...acc.context._queryParams,\n ...result._queryParams,\n },\n _sources: {\n ...acc.context._sources,\n ...result._sources,\n },\n _AsyncProcess: {\n ...acc.context._AsyncProcess,\n ...result._AsyncProcess,\n },\n _cloudProxy: {\n ...acc.context._cloudProxy,\n ...result._cloudProxy,\n },\n _dependencies: {\n ...acc.context._dependencies,\n ...result._dependencies,\n },\n _error: {\n ...acc.context._error,\n ...result._error,\n },\n },\n propsAndMethods: {\n ...acc.propsAndMethods,\n ...result.props,\n ...result.methods,\n },\n };\n },\n {\n context: {\n props: {},\n methods: {},\n _inputs: {}, // passing pluggableInputs here seems to not works\n _queryParams: {},\n _sources: {},\n _injections: {},\n _mutation: {},\n _query: {},\n _AsyncProcess: {},\n _cloudProxy: {},\n _dependencies: {},\n _error: {},\n } as _EmptyContext,\n propsAndMethods: {},\n } as {\n context: _EmptyContext;\n propsAndMethods: {};\n },\n );\n}\n","import {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { capitalize } from './util/util';\nimport {\n FilterMethodsBoundToSources,\n Prettify,\n UnionToTuple,\n} from './util/util.type';\nimport { AsyncProcessRef } from './async-process';\n\ntype SpecificCraftAsyncProcessesOutputs<AsyncProcess extends {}> =\n PartialContext<{\n props: {\n [key in keyof AsyncProcess]: Prettify<Omit<AsyncProcess[key], 'method'>>;\n };\n methods: FilterMethodsBoundToSources<\n AsyncProcess,\n UnionToTuple<keyof AsyncProcess>,\n 'set',\n 'method'\n >;\n _AsyncProcess: {\n [key in keyof AsyncProcess]: Prettify<Omit<AsyncProcess[key], 'method'>>;\n };\n }>;\n\ntype craftAsyncProcessesOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n AsyncProcess extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftAsyncProcessesOutputs<AsyncProcess>\n>;\n\n/**\n * Creates async method definitions for use within a craft store, enabling reactive management of asynchronous operations.\n *\n * This function integrates multiple `AsyncProcess()` instances into a craft store by:\n * - Registering async methods as a group with automatic state tracking\n * - Generating prefixed `set` methods for each async method (e.g., `setMethodName`)\n * - Exposing async method state signals (value, status, error, isLoading)\n * - Supporting both method-based and source-based async method triggering\n * - Managing async methods with identifiers for parallel execution\n * - Enabling insertions for extending functionality (persistence, etc.)\n *\n * @remarks\n * **Naming Convention:**\n * - Async methods are accessible as: `store.methodName` (returns signals and state)\n * - Trigger methods are prefixed: `store.setMethodName(args)`\n * - Source-based async methods (bound to sources) don't expose `set` methods\n *\n * **Difference from Mutations:**\n * - **Async Methods**: General-purpose async operations without automatic query coordination\n * - **Mutations**: Server data modifications with built-in query synchronization patterns\n * - Use async methods for operations like debounced search, background tasks\n * - Use mutations for CRUD operations that should update query caches\n *\n * **Use Cases:**\n * - **Debounced operations**: Search, validation, autosave with delay\n * - **Background tasks**: Processing, computation without blocking UI\n * - **Third-party APIs**: External service calls with status tracking\n * - **Polling**: Periodic checks or updates\n * - **Cancellable operations**: Long-running tasks with abort capability\n *\n * **Context Access:**\n * The async methods factory receives full access to the craft context:\n * - Sources: Bind async methods to sources for automatic execution\n * - Queries: Access query state for conditional logic\n * - States: Read and react to state changes\n * - Injections: Access Angular services and dependencies\n *\n * **Store Integration:**\n * - Async method state accessible as: `store.methodName.value()`, `store.methodName.status()`\n * - Trigger async methods: `store.setMethodName(args)`\n * - With identifier: `store.methodName.select(id)` for individual instances\n * - Context access: Other craft entries can access async methods for coordination\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template AsyncProcess - Record of async method names to async method instances\n *\n * @param AsyncProcessFactory - Factory function that receives the craft context and returns a record of async methods.\n * Has access to all other craft entries (sources, queries, states, injections) defined before it.\n *\n * @returns A craft factory utility that integrates async methods into the store with:\n * - `store.methodName`: Async method state and signals\n * - `store.setMethodName(args)`: Method to trigger the async operation (for method-based async methods)\n * - Full type safety for async method parameters and results\n *\n * @example\n * Basic method-based async method\n * ```ts\n * const delay = asyncProcess({\n * method: (delay: number) => delay,\n * loader: async ({ params }) => {\n * await new Promise(resolve => setTimeout(resolve, 500)); // Simulate delay\n * return 'done';\n * },\n * });\n *\n * // Trigger manually\n * delay.method(500);\n *\n * // Track state\n * console.log(delay.status()); // 'loading'\n * console.log(delay.isLoading()); // true\n *\n * // After completion\n * console.log(delay.status()); // 'resolved'\n * console.log(delay.value()); // 'done'\n * console.log(delay.hasValue()); // true\n * ```\n *\n * @example\n * Source-based async method for automatic execution\n * ```ts\n * const delaySource = source<number>();\n *\n * const delay = asyncProcess({\n * method: afterRecomputation(delaySource, (term) => term),\n * loader: async ({ params }) => {\n * // Debounce at source level\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done';\n * },\n * });\n *\n * // Triggers automatically when source emits\n * delaySource.set(500);\n * // -> delay executes automatically\n *\n * // No manual method, only source\n * console.log(delay.source); // ReadonlySource<number>\n * console.log(delay.status()); // Current state\n * ```\n *\n * @example\n * Async method with identifier for parallel operations\n * ```ts\n * const delayById = asyncProcess({\n * method: (id: string) => id,\n * identifier: (id) => id,\n * loader: async () => {\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done'; // Simulate delay\n * },\n * });\n *\n * delayById.method('id1');\n * delayById.method('id2');\n * delayById.method('id3');\n *\n * // Access individual states\n * const delay1 = delayById.select('id1');\n * console.log(delay1?.status()); // 'loading' or 'resolved'\n * console.log(delay1?.value()); // 'done'\n *\n * const delay2 = delayById.select('id2');\n * console.log(delay2?.status()); // Independent state\n * ```\n *\n * @example\n * Calling async js native API\n * ```ts\n * const shareContent = asyncProcess({\n * method: (payload: { title: string, url: string }) => payload,\n * stream: async ({ params }) => {\n * return navigator.share(params);\n * },\n * }, ({resource}) => ({isMenuOpen: computed(() => resource.status() === 'loading')} ));\n *\n * // Trigger shareContent\n * shareContent.method({ title: 'Hello AI!', url: 'https://example.com' });\n * shareContent.isMenuOpen(); // true while loading\n *\n * ```\n */\nexport function craftAsyncProcesses<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n AsyncProcess extends {},\n>(\n AsyncProcessFactory: (context: CraftFactoryEntries<Context>) => AsyncProcess,\n): craftAsyncProcessesOutputs<Context, StoreConfig, AsyncProcess> {\n return (_cloudProxy) => (contextData) => {\n const AsyncProcess = AsyncProcessFactory(\n craftFactoryEntries(contextData),\n ) as Record<\n string,\n AsyncProcessRef<\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown\n >\n >;\n\n const { methods, resourceRefs } = Object.entries(AsyncProcess ?? {}).reduce(\n (acc, [methodName, AsyncProcessRef]) => {\n const methodValue =\n 'method' in AsyncProcessRef ? AsyncProcessRef.method : undefined;\n if (!methodValue) {\n acc.resourceRefs[methodName] = AsyncProcessRef;\n return acc;\n }\n acc.resourceRefs[methodName] = {\n ...AsyncProcessRef,\n };\n acc.methods[`set${capitalize(methodName)}`] = methodValue as Function;\n return acc;\n },\n {\n methods: {},\n resourceRefs: {},\n } as {\n resourceRefs: Record<\n string,\n Omit<\n AsyncProcessRef<\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown\n >,\n 'method' | 'source'\n >\n >;\n methods: Record<string, Function>;\n },\n );\n\n return partialContext({\n props: resourceRefs,\n methods,\n _AsyncProcess: resourceRefs,\n }) as unknown as SpecificCraftAsyncProcessesOutputs<AsyncProcess>;\n };\n}\n","import { Signal } from '@angular/core';\nimport {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\n\ntype SpecificCraftComputedOutputs<Computed extends {}> = PartialContext<{\n props: Computed;\n}>;\n\ntype CraftComputedStatesOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Computed extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftComputedOutputs<Computed>\n>;\n\n/**\n * Creates computed signals derived from other craft store entries (queries, mutations, states).\n *\n * This function enables reactive derived values in craft stores by:\n * - Creating computed signals that automatically update when dependencies change\n * - Deriving values from queries, mutations, states, and other computed signals\n * - Exposing computed values directly on the store (no prefix)\n * - Providing full type safety for computed values\n * - Enabling complex transformations and combinations of store data\n * - Supporting memo-ization for performance optimization\n *\n * @remarks\n * **Naming Convention:**\n * - Computed signals are accessible directly: `store.computedName()`\n * - No prefix added (unlike queries/mutations)\n * - Access pattern is identical to regular Angular signals\n *\n * **Use Cases:**\n * - **Derived data**: Calculate values based on query/state results (totals, counts, filtered lists)\n * - **Data transformation**: Format or reshape data from queries\n * - **Aggregation**: Combine data from multiple queries or states\n * - **Status derivation**: Compute loading states from multiple queries\n * - **Validation**: Derive validation status from form states\n * - **UI state**: Calculate UI flags based on multiple conditions\n *\n * **Context Access:**\n * - Computed factory receives full access to the craft context\n * - Can access queries, mutations, states, sources, and other computed values\n * - Context entries are accessed as signals: `context.queryName()`, `context.stateName()`\n *\n * **Reactive Behavior:**\n * - Computed signals automatically update when dependencies change\n * - Only recompute when accessed and dependencies have changed (memo-ized)\n * - Follow Angular's computed signal semantics\n * - Can be used in templates and effects like any signal\n *\n * **Performance:**\n * - Computed values are cached and only recompute when necessary\n * - Multiple accesses without dependency changes don't trigger recomputation\n * - Efficient for expensive calculations or transformations\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Computed - Record of computed signal names to signal types\n *\n * @param computedFactory - Factory function that receives the craft context and returns a record of computed signals.\n * Has access to all other craft entries (queries, mutations, states) defined before it.\n *\n * @returns A craft factory utility that:\n * - Creates computed signals based on store data\n * - Exposes them directly on the store\n * - Provides full type safety for computed values\n *\n * @example\n * Basic computed values from state\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('count', () => state(0)),\n * craftComputedStates(({ count }) => ({\n * doubled: computed(() => count() * 2),\n * isEven: computed(() => count() % 2 === 0),\n * message: computed(() => `Count is ${count()}`),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * console.log(store.doubled()); // 0\n * console.log(store.isEven()); // true\n *\n * store.setCount(5);\n * console.log(store.doubled()); // 10\n * console.log(store.isEven()); // false\n * console.log(store.message()); // 'Count is 5'\n * ```\n *\n * @example\n * Computed values from query results\n * ```ts\n * type Todo = { id: string; text: string; done: boolean };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('todos', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json() as Todo[];\n * },\n * })\n * ),\n * craftComputedStates(({ todos }) => ({\n * completedCount: computed(() => {\n * const list = todos.value();\n * return list?.filter(t => t.done).length ?? 0;\n * }),\n * pendingCount: computed(() => {\n * const list = todos.value();\n * return list?.filter(t => !t.done).length ?? 0;\n * }),\n * totalCount: computed(() => todos.value()?.length ?? 0),\n * allCompleted: computed(() => {\n * const list = todos.value();\n * return list ? list.length > 0 && list.every(t => t.done) : false;\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Use in template\n * // <div>{{ store.completedCount() }} / {{ store.totalCount() }} completed</div>\n * // <button [disabled]=\"store.allCompleted()\">Complete All</button>\n * ```\n *\n * @example\n * Combining multiple queries\n * ```ts\n * type User = { id: string; name: string };\n * type Post = { id: string; userId: string; title: string };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('users', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/users');\n * return response.json() as User[];\n * },\n * })\n * ),\n * craftQuery('posts', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/posts');\n * return response.json() as Post[];\n * },\n * })\n * ),\n * craftComputedStates(({ users, posts }) => ({\n * postsWithAuthors: computed(() => {\n * const userList = users.value();\n * const postList = posts.value();\n *\n * if (!userList || !postList) return [];\n *\n * return postList.map(post => ({\n * ...post,\n * author: userList.find(u => u.id === post.userId),\n * }));\n * }),\n * userPostCount: computed(() => {\n * const postList = posts.value();\n * if (!postList) return new Map();\n *\n * return postList.reduce((map, post) => {\n * map.set(post.userId, (map.get(post.userId) ?? 0) + 1);\n * return map;\n * }, new Map<string, number>());\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Automatically combines data from both queries\n * const enrichedPosts = store.postsWithAuthors();\n * const postCounts = store.userPostCount();\n * ```\n *\n * @example\n * Loading state aggregation\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('sales', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/sales');\n * return response.json();\n * },\n * })\n * ),\n * craftQuery('analytics', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/analytics');\n * return response.json();\n * },\n * })\n * ),\n * craftComputedStates(({ sales, analytics }) => ({\n * isLoading: computed(() =>\n * sales.isLoading() || analytics.isLoading()\n * ),\n * hasError: computed(() =>\n * sales.error() !== undefined || analytics.error() !== undefined\n * ),\n * allLoaded: computed(() =>\n * sales.hasValue() && analytics.hasValue()\n * ),\n * errorMessage: computed(() => {\n * const salesError = sales.error();\n * const analyticsError = analytics.error();\n *\n * if (salesError) return `Sales error: ${salesError.message}`;\n * if (analyticsError) return `Analytics error: ${analyticsError.message}`;\n * return null;\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Use in template for unified loading state\n * // @if (store.isLoading()) { <spinner /> }\n * // @if (store.hasError()) { <error>{{ store.errorMessage() }}</error> }\n * // @if (store.allLoaded()) { <dashboard /> }\n * ```\n *\n * @example\n * Chaining computed values\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('items', () =>\n * state([] as Array<{ id: string; price: number; quantity: number }>)\n * ),\n * craftComputedStates(({ items }) => ({\n * subtotal: computed(() =>\n * items().reduce((sum, item) => sum + item.price * item.quantity, 0)\n * ),\n * })),\n * craftComputedStates(({ subtotal }) => ({\n * // Can depend on other computed values\n * tax: computed(() => subtotal() * 0.1),\n * shipping: computed(() => subtotal() > 100 ? 0 : 10),\n * })),\n * craftComputedStates(({ subtotal, tax, shipping }) => ({\n * // Combine multiple computed values\n * total: computed(() => subtotal() + tax() + shipping()),\n * formatted: computed(() => ({\n * subtotal: `$${subtotal().toFixed(2)}`,\n * tax: `$${tax().toFixed(2)}`,\n * shipping: shipping() === 0 ? 'FREE' : `$${shipping().toFixed(2)}`,\n * total: `$${(subtotal() + tax() + shipping()).toFixed(2)}`,\n * })),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * console.log(store.formatted());\n * // { subtotal: '$0.00', tax: '$0.00', shipping: '$10.00', total: '$10.00' }\n * ```\n *\n * @example\n * Data transformation and filtering\n * ```ts\n * type Product = {\n * id: string;\n * name: string;\n * category: string;\n * price: number;\n * inStock: boolean;\n * };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('products', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/products');\n * return response.json() as Product[];\n * },\n * })\n * ),\n * craftState('selectedCategory', () => state<string | null>(null)),\n * craftState('maxPrice', () => state<number | null>(null)),\n * craftComputedStates(({ products, selectedCategory, maxPrice }) => ({\n * filteredProducts: computed(() => {\n * const list = products.value();\n * if (!list) return [];\n *\n * let filtered = list;\n *\n * const category = selectedCategory();\n * if (category) {\n * filtered = filtered.filter(p => p.category === category);\n * }\n *\n * const price = maxPrice();\n * if (price !== null) {\n * filtered = filtered.filter(p => p.price <= price);\n * }\n *\n * return filtered;\n * }),\n * availableProducts: computed(() => {\n * const list = products.value();\n * return list?.filter(p => p.inStock) ?? [];\n * }),\n * categories: computed(() => {\n * const list = products.value();\n * if (!list) return [];\n *\n * return [...new Set(list.map(p => p.category))];\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Filters update reactively\n * store.setSelectedCategory('electronics');\n * store.setMaxPrice(500);\n * const filtered = store.filteredProducts(); // Automatically filtered\n * ```\n *\n * @example\n * Validation computed values\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('email', () => state('')),\n * craftState('password', () => state('')),\n * craftState('confirmPassword', () => state('')),\n * craftComputedStates(({ email, password, confirmPassword }) => ({\n * isEmailValid: computed(() => {\n * const value = email();\n * return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n * }),\n * isPasswordValid: computed(() => {\n * const value = password();\n * return value.length >= 8;\n * }),\n * doPasswordsMatch: computed(() => {\n * return password() === confirmPassword();\n * }),\n * isFormValid: computed(() => {\n * const emailValid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email());\n * const passwordValid = password().length >= 8;\n * const passwordsMatch = password() === confirmPassword();\n *\n * return emailValid && passwordValid && passwordsMatch;\n * }),\n * validationErrors: computed(() => {\n * const errors: string[] = [];\n *\n * if (email() && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email())) {\n * errors.push('Invalid email format');\n * }\n * if (password() && password().length < 8) {\n * errors.push('Password must be at least 8 characters');\n * }\n * if (confirmPassword() && password() !== confirmPassword()) {\n * errors.push('Passwords do not match');\n * }\n *\n * return errors;\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Use in template\n * // <button [disabled]=\"!store.isFormValid()\">Submit</button>\n * // @for (error of store.validationErrors(); track error) {\n * // <div class=\"error\">{{ error }}</div>\n * // }\n * ```\n */\nexport function craftComputedStates<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Computed extends {},\n>(\n computedFactory: (context: CraftFactoryEntries<Context>) => Computed,\n): CraftComputedStatesOutputs<Context, StoreConfig, Computed> {\n return () => (contextData) => {\n const computedValues = computedFactory(\n craftFactoryEntries(contextData),\n ) as Record<string, Signal<unknown>>;\n\n return partialContext({\n props: computedValues,\n }) as SpecificCraftComputedOutputs<Computed>;\n };\n}\n","import { InjectionToken, Type } from '@angular/core';\nimport {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\n\ntype ProviderTokenWithoutAbstract<T> = Type<T> | InjectionToken<T>;\n\ntype InferProvidedType<T> =\n T extends ProviderTokenWithoutAbstract<infer U> ? U : never;\n\ntype SpecificCraftInjectionsOutputs<Injections extends {}> = PartialContext<{\n _injections: {\n [key in keyof Injections as Uncapitalize<key & string>]: InferProvidedType<\n Injections[key]\n >;\n };\n}>;\n\ntype CraftInputsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Injections extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftInjectionsOutputs<Injections>\n>;\n\n// todo checker si ok avec les token si valeur bien infer / service / token et générics\n\n/**\n * Injects Angular services and tokens into a craft store, making them accessible to all craft entries.\n *\n * This function integrates Angular's dependency injection system into craft stores by:\n * - Injecting services, injection tokens, and providers\n * - Making injected dependencies accessible in all craft entries (queries, mutations, states)\n * - Supporting generic services with type parameters\n * - Automatically converting injection keys to camelCase for context access\n * - Providing full type safety for injected dependencies\n * - Accessing services outside of direct injection context\n *\n * @remarks\n * **Naming Convention:**\n * - Define injections with PascalCase keys: `{ MyService, UserRepository }`\n * - Access in context with camelCase: `context.myService`, `context.userRepository`\n * - Automatic conversion preserves type information\n *\n * **Use Cases:**\n * - **Service integration**: Access Angular services (HttpClient, Router, etc.) in queries/mutations\n * - **API clients**: Inject custom API service classes for data fetching\n * - **State services**: Access existing Angular services that manage state\n * - **Configuration**: Inject configuration tokens and environment settings\n * - **Third-party libraries**: Access library services and utilities\n * - **Testing**: Mock services by providing test implementations\n *\n * **Injection Types:**\n * - **Services**: Injectable classes marked with `@Injectable()`\n * - **Injection Tokens**: `InjectionToken<T>` for non-class dependencies\n * - **Generic Services**: Services with type parameters `Service<T>`\n * - **Abstract Classes**: Base classes with implementations provided elsewhere\n *\n * **Context Access:**\n * - Injections available in all craft entries via context parameter\n * - Access pattern: `context.serviceName` (lowercase first letter)\n * - Can access other context entries in the injection factory function\n *\n * **Reactive Integration:**\n * - Services can expose signals that queries/mutations react to\n * - Service methods can be called from query loaders or mutation handlers\n * - Injected services maintain their own lifecycle and state\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Injections - Record of injection keys to provider types\n *\n * @param injections - Factory function that receives the craft context and returns a record of injections.\n * Keys should be PascalCase (matching service/token names), values should be service classes or injection tokens.\n * Has access to all other craft entries defined before it.\n *\n * @returns A craft factory utility that:\n * - Injects all specified dependencies using Angular's injector\n * - Makes them accessible in camelCase in the craft context\n * - Provides full type safety for injected services\n *\n * @example\n * Basic service injection\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class UserApiService {\n * constructor(private http: HttpClient) {}\n *\n * getUser(id: string) {\n * return this.http.get<User>(`/api/users/${id}`);\n * }\n *\n * updateUser(user: User) {\n * return this.http.patch<User>(`/api/users/${user.id}`, user);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * UserApiService, // Inject the service\n * })),\n * craftQuery('user', ({ userApiService }) =>\n * query({\n * params: () => 'user-123',\n * loader: async ({ params }) => {\n * // Use the injected service\n * return firstValueFrom(userApiService.getUser(params));\n * },\n * })\n * ),\n * craftMutations(({ userApiService }) => ({\n * updateUser: mutation({\n * method: (user: User) => user,\n * loader: async ({ params }) => {\n * // Use the injected service in mutation\n * return firstValueFrom(userApiService.updateUser(params));\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n * // Service is used internally by queries and mutations\n * ```\n *\n * @example\n * Multiple service injections\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class AuthService {\n * currentUser = signal<User | null>(null);\n *\n * isAuthenticated() {\n * return this.currentUser() !== null;\n * }\n * }\n *\n * @Injectable({ providedIn: 'root' })\n * class ApiClient {\n * constructor(private http: HttpClient) {}\n *\n * get<T>(url: string) {\n * return this.http.get<T>(url);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * AuthService,\n * ApiClient,\n * Router, // Can inject Angular services too\n * })),\n * craftQuery('protectedData', ({ authService, apiClient }) =>\n * query({\n * params: () => authService.currentUser()?.id,\n * loader: async ({ params }) => {\n * if (!params) return null;\n * return firstValueFrom(apiClient.get(`/api/protected/${params}`));\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Queries automatically react to authService.currentUser changes\n * ```\n *\n * @example\n * Injection tokens for configuration\n * ```ts\n * interface AppConfig {\n * apiUrl: string;\n * timeout: number;\n * }\n *\n * const APP_CONFIG = new InjectionToken<AppConfig>('APP_CONFIG', {\n * providedIn: 'root',\n * factory: () => ({\n * apiUrl: 'https://api.example.com',\n * timeout: 5000,\n * }),\n * });\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * AppConfig: APP_CONFIG, // Inject token\n * })),\n * craftQuery('data', ({ appConfig }) =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * // Use config from token\n * const response = await fetch(`${appConfig.apiUrl}/data`, {\n * signal: AbortSignal.timeout(appConfig.timeout),\n * });\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Queries use configuration from injection token\n * ```\n *\n * @example\n * Generic service injection\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class Repository<T> {\n * private cache = new Map<string, T>();\n *\n * get(id: string): T | undefined {\n * return this.cache.get(id);\n * }\n *\n * set(id: string, value: T): void {\n * this.cache.set(id, value);\n * }\n * }\n *\n * type Product = { id: string; name: string; price: number };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * ProductRepository: Repository<Product>, // Specify generic type\n * })),\n * craftQuery('product', ({ productRepository }) =>\n * query({\n * params: () => 'product-1',\n * loader: async ({ params }) => {\n * // Check cache first\n * const cached = productRepository.get(params);\n * if (cached) return cached;\n *\n * // Fetch and cache\n * const response = await fetch(`/api/products/${params}`);\n * const product = await response.json();\n * productRepository.set(params, product);\n * return product;\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // productRepository is typed as Repository<Product>\n * ```\n *\n * @example\n * Service with signals for reactive state\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class FilterService {\n * searchTerm = signal('');\n * selectedCategory = signal<string | null>(null);\n *\n * setSearch(term: string) {\n * this.searchTerm.set(term);\n * }\n *\n * setCategory(category: string | null) {\n * this.selectedCategory.set(category);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * FilterService,\n * })),\n * craftQuery('products', ({ filterService }) =>\n * query({\n * params: () => ({\n * search: filterService.searchTerm(),\n * category: filterService.selectedCategory(),\n * }),\n * loader: async ({ params }) => {\n * const query = new URLSearchParams({\n * search: params.search,\n * category: params.category ?? '',\n * });\n * const response = await fetch(`/api/products?${query}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Query automatically re-executes when filter signals change\n *\n * // In a component\n * export class FilterComponent {\n * filterService = inject(FilterService);\n *\n * onSearch(term: string) {\n * this.filterService.setSearch(term);\n * // Store query reacts automatically\n * }\n * }\n * ```\n *\n * @example\n * Accessing context entries in injection factory\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class LoggingService {\n * log(message: string) {\n * console.log(`[LOG] ${message}`);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * error: source<Error>(),\n * }),\n * craftInject(({ error }) => {\n * // Can access previous context entries\n * return {\n * LoggingService,\n * };\n * }),\n * craftState('errorLog', ({ error, loggingService }) =>\n * state([] as string[], {\n * bindSources: {\n * error: (errors, err) => {\n * // Use injected service\n * loggingService.log(`Error occurred: ${err.message}`);\n * return [...errors, err.message];\n * },\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * store.setError(new Error('Something went wrong'));\n * // Logging service is used to log the error\n * ```\n *\n * @example\n * Complex service composition\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class CacheService {\n * private cache = new Map<string, { data: unknown; timestamp: number }>();\n *\n * get<T>(key: string, maxAge: number): T | null {\n * const entry = this.cache.get(key);\n * if (!entry) return null;\n *\n * if (Date.now() - entry.timestamp > maxAge) {\n * this.cache.delete(key);\n * return null;\n * }\n *\n * return entry.data as T;\n * }\n *\n * set(key: string, data: unknown): void {\n * this.cache.set(key, { data, timestamp: Date.now() });\n * }\n * }\n *\n * @Injectable({ providedIn: 'root' })\n * class HttpService {\n * constructor(\n * private http: HttpClient,\n * private cache: CacheService\n * ) {}\n *\n * async fetchWithCache<T>(url: string, cacheKey: string): Promise<T> {\n * // Check cache (5 minute expiry)\n * const cached = this.cache.get<T>(cacheKey, 5 * 60 * 1000);\n * if (cached) return cached;\n *\n * // Fetch and cache\n * const data = await firstValueFrom(this.http.get<T>(url));\n * this.cache.set(cacheKey, data);\n * return data;\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * HttpService,\n * })),\n * craftQuery('userData', ({ httpService }) =>\n * query({\n * params: () => 'user-123',\n * loader: async ({ params }) => {\n * // Service handles caching internally\n * return httpService.fetchWithCache(\n * `/api/users/${params}`,\n * `user-${params}`\n * );\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Queries benefit from service's internal caching\n * ```\n */\nexport function craftInject<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Injections extends {},\n>(\n injections: (entries: CraftFactoryEntries<Context>) => Injections,\n): CraftInputsOutputs<Context, StoreConfig, Injections> {\n return () => (contextData, injector) => {\n const injectedInjections = Object.entries(\n injections(craftFactoryEntries(contextData)),\n ).reduce(\n (acc, [key, injection]) => ({\n ...acc,\n [uncapitalize(key)]: injector.get(injection as any),\n }),\n {},\n );\n return partialContext({\n _injections: injectedInjections,\n }) as SpecificCraftInjectionsOutputs<Injections>;\n };\n}\n\nfunction uncapitalize(str: string) {\n return str.charAt(0).toLowerCase() + str.slice(1);\n}\n","import { Signal } from '@angular/core';\nimport {\n ContextConstraints,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { Prettify } from './util/util.type';\n\ntype ToSignalObject<T> = {\n [K in keyof T]: Signal<T[K]>;\n};\n\ntype SpecificCraftInputsOutputs<Inputs extends {}> = PartialContext<{\n _inputs: Prettify<ToSignalObject<Inputs>>;\n}>;\n\ntype CraftInputsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Inputs extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftInputsOutputs<Inputs>\n>;\n\n/**\n * Creates input definitions for use within a craft store, enabling dynamic parameter injection from components.\n *\n * This function enables external data to be passed into a craft store by:\n * - Defining a schema of expected input parameters with their types\n * - Converting input values to signals automatically\n * - Making inputs accessible to all craft entries (queries, mutations, states)\n * - Providing type-safe parameter passing from components to store\n * - Enabling reactive updates when input values change\n *\n * @remarks\n * **Use Cases:**\n * - **Dynamic parameters**: Pass component-specific data to queries (e.g., route params, user selections)\n * - **External signals**: Inject signals from parent components or services\n * - **Conditional loading**: Control when queries execute based on input availability\n * - **Multi-instance stores**: Create store instances with different input configurations\n * - **Component coordination**: Share component state with store logic\n *\n * **Input Definition:**\n * - Define inputs as a record of keys with their types\n * - Inputs are automatically converted to signals in the context\n *\n * **Context Access:**\n * - Inputs are accessible in all craft entries via the context parameter\n * - Access as: `context.inputName` in query/mutation/state factories\n * - Inputs are available as signals: `context.inputName()` returns the value\n *\n * **Store Injection:**\n * - When injecting the store, pass actual signal values: `injectCraft({ inputs: { inputName: signal(value) } })`\n * - TypeScript enforces providing all required inputs\n *\n * **Reactive Behavior:**\n * - When input signals change, dependent queries automatically re-execute\n * - Mutations and states can react to input changes\n * - Use with `params: () => context.inputName()` for reactive queries\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Inputs - Record of input names to their value types\n *\n * @param inputs - Schema object defining input names and their types.\n * Values are used for type inference only; actual values are provided during injection.\n *\n * @returns A craft factory utility that:\n * - Adds inputs to the store context for use by other craft entries\n * - Requires input signals to be provided when injecting the store\n * - Provides full type safety for input values\n *\n * @example\n * Basic inputs for dynamic query parameters\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInputs({\n * userId: undefined as string | undefined,\n * }),\n * craftQuery('user', ({ userId }) =>\n * query({\n * params: userId, // Uses the input signal directly\n * loader: async ({ params }) => {\n * if (!params) return undefined;\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * // In a component\n * @Component({\n * selector: 'app-user-profile',\n * template: `\n * @if (store.user.value()) {\n * <div>{{ store.user.value().name }}</div>\n * }\n * `,\n * })\n * export class UserProfileComponent {\n * route = inject(ActivatedRoute);\n *\n * // Create signal from route param\n * userId = toSignal(this.route.params.pipe(map(p => p['id'])));\n *\n * // Inject store with input\n * store = injectCraft({\n * inputs: {\n * userId: this.userId, // Pass the signal\n * },\n * });\n * }\n *\n * // Query automatically executes and re-executes when userId changes\n * ```\n *\n * @example\n * Inputs shared across multiple craft entries\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInputs({\n * dateRange: undefined as { start: Date; end: Date } | undefined,\n * userId: undefined as string | undefined,\n * }),\n * craftQuery('sales', ({ dateRange, userId }) =>\n * query({\n * params: () => ({ dateRange: dateRange(), userId: userId() }),\n * loader: async ({ params }) => {\n * if (!params.dateRange || !params.userId) return null;\n * const response = await fetch('/api/sales', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * })\n * ),\n * craftQuery('analytics', ({ dateRange, userId }) =>\n * query({\n * params: () => ({ dateRange: dateRange(), userId: userId() }),\n * loader: async ({ params }) => {\n * if (!params.dateRange || !params.userId) return null;\n * const response = await fetch('/api/analytics', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * // Both queries use the same inputs\n * export class DashboardComponent {\n * dateRange = signal<{ start: Date; end: Date } | undefined>(undefined);\n * userId = signal<string | undefined>('user-123');\n *\n * store = injectCraft({\n * inputs: {\n * dateRange: this.dateRange,\n * userId: this.userId,\n * },\n * });\n *\n * // Both queries re-execute when inputs change\n * updateDateRange(start: Date, end: Date) {\n * this.dateRange.set({ start, end });\n * }\n * }\n * ```\n */\nexport function craftInputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Inputs extends {},\n>(inputs: Inputs): CraftInputsOutputs<Context, StoreConfig, Inputs> {\n // todo expose setXInputs as standalone ?\n return () => () => {\n return partialContext({\n _inputs: inputs,\n }) as SpecificCraftInputsOutputs<Inputs>;\n };\n}\n","import {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { UnionToTuple, Prettify } from './util/util.type';\nimport { capitalize } from './util/util';\nimport { FilterMethodsBoundToSources } from './util/util.type';\nimport { MutationRef } from './mutation';\n\ntype SpecificCraftMutationsOutputs<Mutations extends {}> = PartialContext<{\n props: {\n [key in keyof Mutations]: Prettify<Omit<Mutations[key], 'mutate'>>;\n };\n methods: FilterMethodsBoundToSources<\n Mutations,\n UnionToTuple<keyof Mutations>,\n 'mutate',\n 'mutate'\n >;\n _mutation: {\n [key in keyof Mutations]: Mutations[key];\n };\n}>;\n\ntype CraftMutationsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Mutations extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftMutationsOutputs<Mutations>\n>;\n\n/**\n * Creates mutation definitions for use within a craft store, enabling reactive management of server-side data modifications.\n *\n * This function integrates multiple `mutation()` instances into a craft store by:\n * - Registering mutations as a group with automatic state tracking\n * - Generating prefixed `mutate` methods for each mutation (e.g., `mutateMutationName`)\n * - Exposing mutation state signals (value, status, error, isLoading)\n * - Enabling queries to react to mutation changes via `insertReactOnMutation()`\n * - Supporting both method-based and source-based mutation triggering\n * - Managing mutations with identifiers for parallel execution\n *\n * @remarks\n * **Naming Convention:**\n * - Mutations are accessible as: `store.mutationName` (returns signals and state)\n * - Trigger methods are prefixed: `store.mutateMutationName(args)`\n * - Source-based mutations (bound to sources) don't expose `mutate` methods\n *\n * **Use Cases:**\n * - **Data modification**: Create, update, delete operations on server data\n * - **Optimistic updates**: Update UI immediately while mutation executes\n * - **Cache invalidation**: Trigger query reloads after mutations complete\n * - **Batch operations**: Execute multiple mutations with individual state tracking\n * - **Form submissions**: Handle form data submission with loading/error states\n *\n * **Context Access:**\n * The mutations factory receives full access to the craft context:\n * - Sources: Bind mutations to sources for automatic execution\n * - Queries: Access query state for conditional mutation logic\n * - Other mutations: Coordinate between multiple mutations\n * - Injections: Access Angular services and dependencies\n *\n * **Integration with Queries:**\n * - Queries can react to mutations via `insertReactOnMutation()`\n * - Supports optimistic updates, patches, full updates, and reloads\n * - Filtered reactions based on mutation identifiers\n *\n * **Store Integration:**\n * - Mutation state accessible as: `store.mutationName.value()`, `store.mutationName.status()`\n * - Trigger mutations: `store.mutateMutationName(args)`\n * - With identifier: `store.mutationName.select(id)` for individual instances\n * - Context access: Other craft entries can access mutations for coordination\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Mutations - Record of mutation names to mutation instances\n *\n * @param mutationsFactory - Factory function that receives the craft context and returns a record of mutations.\n * Has access to all other craft entries (sources, queries, inputs, injections) defined before it.\n *\n * @returns A craft factory utility that integrates mutations into the store with:\n * - `store.mutationName`: Mutation state and signals\n * - `store.mutateMutationName(args)`: Method to trigger the mutation (for method-based mutations)\n * - Full type safety for mutation parameters and results\n *\n * @example\n * Basic mutations for CRUD operations\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * createTodo: mutation({\n * method: (data: { text: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/todos', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * updateTodo: mutation({\n * method: (todo: Todo) => todo,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * deleteTodo: mutation({\n * method: (todoId: string) => ({ todoId }),\n * loader: async ({ params }) => {\n * await fetch(`/api/todos/${params.todoId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Create a new todo\n * store.mutateCreateTodo({ text: 'Buy milk' });\n * console.log(store.createTodo.status()); // 'loading'\n *\n * // After completion\n * console.log(store.createTodo.status()); // 'resolved'\n * console.log(store.createTodo.value()); // { id: '1', text: 'Buy milk', ... }\n *\n * // Update an existing todo\n * store.mutateUpdateTodo({ id: '1', text: 'Buy milk and eggs', done: false });\n *\n * // Delete a todo\n * store.mutateDeleteTodo('1');\n * ```\n *\n * @example\n * Mutations with identifiers for parallel execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateUser: mutation({\n * method: (user: User) => user,\n * identifier: (user) => user.id,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Trigger multiple mutations in parallel\n * store.mutateUpdateUser({ id: 'user-1', name: 'Alice' });\n * store.mutateUpdateUser({ id: 'user-2', name: 'Bob' });\n * store.mutateUpdateUser({ id: 'user-3', name: 'Charlie' });\n *\n * // Access individual mutation states\n * const user1Mutation = store.updateUser.select('user-1');\n * console.log(user1Mutation?.status()); // 'loading' or 'resolved'\n * console.log(user1Mutation?.value()); // { id: 'user-1', name: 'Alice', ... }\n *\n * const user2Mutation = store.updateUser.select('user-2');\n * console.log(user2Mutation?.status()); // Independent state\n * ```\n *\n * @example\n * Mutations coordinated with queries via insertReactOnMutation\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * createPost: mutation({\n * method: (data: CreatePostData) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('posts', ({ createPost }) =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/posts');\n * return response.json();\n * },\n * },\n * insertReactOnMutation(createPost, {\n * // Reload posts list when create completes\n * reload: { onMutationResolved: true },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Create a post - posts query reloads automatically\n * store.mutateCreatePost({ title: 'New Post', content: 'Content...' });\n * // -> createPost mutation executes\n * // -> posts query automatically reloads when mutation resolves\n * ```\n *\n * @example\n * Source-based mutations (automatic execution)\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * submitForm: source<FormData>(),\n * }),\n * craftMutations(({ submitForm }) => ({\n * submit: mutation({\n * method: afterRecomputation(submitForm, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Mutation executes automatically when source emits\n * store.setSubmitForm({ name: 'John', email: 'john@example.com' });\n * // -> submit mutation executes automatically\n * // Note: No mutateSubmit method exposed (source-based)\n *\n * // Access mutation state\n * console.log(store.submit.status()); // 'loading'\n * console.log(store.submit.value()); // Result after completion\n * ```\n *\n * @example\n * Mutations accessing other context entries\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('currentUser', () =>\n * query({\n * params: () => currentUserId(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * ),\n * craftMutations(({ currentUser }) => ({\n * updateProfile: mutation({\n * method: (data: ProfileData) => data,\n * loader: async ({ params }) => {\n * // Access current user from query\n * const userId = currentUser.value()?.id;\n * if (!userId) throw new Error('User not loaded');\n *\n * const response = await fetch(`/api/users/${userId}/profile`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Mutation uses current user from query\n * store.mutateUpdateProfile({ bio: 'New bio', avatar: 'avatar.jpg' });\n * ```\n *\n * @example\n * Multiple mutations with different trigger patterns\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * autoSave: source<SaveData>(),\n * }),\n * craftMutations(({ autoSave }) => ({\n * // Manual mutation\n * manualSave: mutation({\n * method: (data: SaveData) => data,\n * loader: async ({ params }) => {\n * await fetch('/api/save', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return { saved: true };\n * },\n * }),\n * // Auto mutation (source-based)\n * autoSave: mutation({\n * method: afterRecomputation(autoSave, (data) => data),\n * loader: async ({ params }) => {\n * await fetch('/api/autosave', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return { autoSaved: true };\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Manual save - explicit call\n * store.mutateManualSave({ content: 'My data' });\n *\n * // Auto save - triggered by source\n * store.setAutoSave({ content: 'Auto saved data' });\n * // No store.mutateAutoSave available (source-based)\n * ```\n *\n * @example\n * Error handling and status tracking\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * uploadFile: mutation({\n * method: (file: File) => file,\n * loader: async ({ params }) => {\n * const formData = new FormData();\n * formData.append('file', params);\n *\n * const response = await fetch('/api/upload', {\n * method: 'POST',\n * body: formData,\n * });\n *\n * if (!response.ok) {\n * throw new Error('Upload failed');\n * }\n *\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Handle upload with status tracking\n * store.mutateUploadFile(selectedFile);\n *\n * // Track upload status\n * effect(() => {\n * const status = store.uploadFile.status();\n * const error = store.uploadFile.error();\n *\n * if (status === 'loading') {\n * console.log('Uploading...');\n * } else if (status === 'resolved') {\n * console.log('Upload complete:', store.uploadFile.value());\n * } else if (status === 'error') {\n * console.error('Upload failed:', error?.message);\n * }\n * });\n * ```\n */\nexport function craftMutations<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Mutations extends {\n [key: string]: {\n kind: 'mutation';\n };\n },\n>(\n mutationsFactory: (context: CraftFactoryEntries<Context>) => Mutations,\n): CraftMutationsOutputs<Context, StoreConfig, Mutations> {\n return (_cloudProxy) => (contextData) => {\n const mutations = mutationsFactory(\n craftFactoryEntries(contextData),\n ) as unknown as Record<\n string,\n MutationRef<unknown, unknown, unknown, unknown, unknown, unknown, unknown>\n >;\n\n const { methods, resourceRefs } = Object.entries(mutations ?? {}).reduce(\n (acc, [methodName, mutationRef]) => {\n const methodValue =\n 'mutate' in mutationRef ? mutationRef.mutate : undefined;\n if (!methodValue) {\n acc.resourceRefs[methodName] = mutationRef;\n return acc;\n }\n acc.resourceRefs[methodName] = mutationRef;\n acc.methods[`mutate${capitalize(methodName)}`] =\n methodValue as Function;\n return acc;\n },\n {\n methods: {},\n resourceRefs: {},\n } as {\n resourceRefs: Record<\n string,\n Omit<\n MutationRef<\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown\n >,\n 'mutate' | 'source'\n >\n >;\n methods: Record<string, Function>;\n },\n );\n\n return partialContext({\n props: resourceRefs,\n methods,\n _mutation: resourceRefs,\n }) as unknown as SpecificCraftMutationsOutputs<Mutations>;\n };\n}\n","import { Injector, isSignal, Signal, WritableSignal } from '@angular/core';\nimport {\n ContextConstraints,\n ContextInput,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { capitalize } from './util/util';\nimport { QueryParamConfig, QueryParamOutput } from './query-param';\nimport { DeferredExtract } from './util/util.type';\n\nexport type SpecificCraftQueryParamOutputs<\n QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n> =\n DeferredExtract<Insertions> extends infer Extracted\n ? Extracted extends { props: unknown; methods: Record<string, Function> }\n ? PartialContext<{\n props: {\n [key in QueryParamsName]: Signal<QueryParamsState>;\n } & {\n [K in keyof QueryParamsState as `${QueryParamsName &\n string}${Capitalize<K & string>}`]: Signal<QueryParamsState[K]>;\n } & {\n [key in keyof Extracted['props'] as `${QueryParamsName &\n string}${Capitalize<key & string>}`]: Extracted['props'][key];\n };\n methods: {\n [key in keyof Extracted['methods'] as `${key & string}${Capitalize<\n QueryParamsName & string\n >}`]: Extracted['methods'][key];\n };\n _queryParams: {\n [K in QueryParamsName]: {\n config: QueryParamsType;\n state: WritableSignal<QueryParamsState>;\n };\n };\n }>\n : never\n : never;\n\ntype SpecificCraftQueryParamStandaloneOutputs<\n QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n> = {\n [K in QueryParamsName as `set${Capitalize<K>}QueryParams`]: <\n T extends Partial<{\n [K in keyof QueryParamsState]: QueryParamsState[K];\n }>,\n >(\n params: T,\n ) => T;\n};\n\ntype CraftQueryParamOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftQueryParamOutputs<\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >,\n SpecificCraftQueryParamStandaloneOutputs<\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >\n>;\n\n/**\n * Creates a craft factory for reactive query parameter management integrated with the craft store.\n *\n * This function integrates query parameter management into a craft store by:\n * - Creating typed signals for each query parameter prefixed with the provided name\n * - Exposing methods to update query parameters\n * - Providing a standalone method to serialize query params for navigation outside injection context\n * - Synchronizing with URL query parameters automatically\n *\n * @remarks\n * **Important:** The `queryParamFactory` function must return a `queryParam()` call.\n * Since `queryParam()` requires an injection context, `craftQueryParam` handles this by:\n * - Calling the factory within an injection context to create the reactive query param manager\n * - Calling the factory outside injection context to extract the configuration for standalone methods\n *\n * **Warning:** Be careful to avoid query params key collisions. (There is no verification yet)\n *\n * @param queryParamsName - Name used to prefix generated signals and methods\n * @param queryParamFactory - Factory function that receives craft context and returns a QueryParamOutput\n * @returns A craft factory function with standalone methods for serializing query params\n *\n * @example\n * Basic usage with craft\n * ```ts\n * const { injectCraft, setPaginationQueryParams } = craft(\n * {\n * providedIn: 'root',\n * name: 'myStore',\n * },\n * craftQueryParam('pagination', () =>\n * queryParam({\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * }, ({set, update, patch, reset}) => ({set, update, patch, reset}))\n * )\n * );\n *\n * // In a component (injection context):\n * const store = injectCraft();\n *\n * // Accessing query param values\n * store.paginationPage(); // Signal<number> for 'page' query param\n * store.paginationPageSize(); // Signal<number> for 'pageSize' query param\n * store.pagination(); // Signal<{ page: number; pageSize: number }>\n *\n * // Updating query param values (also updates URL)\n * store.setPagination({ page: 2, pageSize: 20 });\n * store.updatePagination(current => ({ ...current, page: current.page + 1 }));\n * store.patchPagination({ pageSize: 50 });\n * store.resetPagination();\n * ```\n *\n * @example\n * Using standalone method for navigation outside injection context\n * ```ts\n * // Outside injection context (e.g., in a route resolver, guard, or service method):\n * async navigateToMyPage() {\n * await router.navigate(['my-page'], {\n * queryParams: setPaginationQueryParams({ page: 4, pageSize: 20 }),\n * });\n * }\n *\n * navigateByUrlToMyPage() {\n * router.navigateByUrl(\n * `/my-page?${setPaginationQueryParams({ page: 4, pageSize: 20 })}`\n * );\n * }\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const { injectCraft } = craft(\n * {\n * providedIn: 'root',\n * name: '',\n * },\n * craftQueryParam('pagination', () =>\n * queryParam(\n * {\n * state: {\n * page: { fallbackValue: 1, parse: parseInt, serialize: String },\n * },\n * },\n * ({ state, set }) => ({\n * goToPage: (newPage: number) => {\n * set({ ...state(), page: newPage });\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n * store.goToPagePagination(5); // Custom method from insertion\n * ```\n */\nexport function craftQueryParam<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n const QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n>(\n queryParamsName: QueryParamsName,\n queryParamFactory: (\n context: CraftFactoryEntries<Context>,\n ) => QueryParamOutput<QueryParamsType, Insertions, QueryParamsState>,\n): CraftQueryParamOutputs<\n Context,\n StoreConfig,\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n> {\n const context = (\n contextData: ContextInput<Context>,\n injector: Injector,\n _storeConfig: StoreConfig,\n _cloudProxy: Context['_cloudProxy'],\n ) => {\n const queryParamState = queryParamFactory(craftFactoryEntries(contextData));\n\n const { props, methods } = Object.entries(queryParamState).reduce(\n (acc, [key, value]) => {\n if (isSignal(value)) {\n (acc.props as Record<string, Signal<any>>)[\n `${queryParamsName}${capitalize(key)}`\n ] = value;\n } else {\n (acc.methods as Record<string, Function>)[\n `${key}${capitalize(queryParamsName)}`\n ] = value;\n }\n return acc;\n },\n { props: {}, methods: {} } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n },\n );\n\n return partialContext({\n props: {\n ...props,\n [`${queryParamsName}`]: queryParamState,\n },\n _queryParams: {\n [`${queryParamsName}`]: {\n config: queryParamState,\n state: queryParamState,\n },\n },\n methods,\n }) as SpecificCraftQueryParamOutputs<\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >;\n };\n\n // when queryParam is called outside the injection context, it will only return the config\n const queryParamsConfig = (\n queryParamFactory({}) as unknown as { _config: QueryParamsType }\n )._config as QueryParamsType;\n\n const setCurrentQueryParams = (\n params: Partial<{\n [K in keyof QueryParamsState]: QueryParamsState[K];\n }>,\n ) =>\n serializeQueryParams(\n params,\n queryParamsConfig as { state: Record<string, QueryParamConfig<unknown>> },\n );\n\n const setCurrentQueryParamsKey = `set${capitalize(\n queryParamsName,\n )}QueryParams`;\n\n return (() =>\n Object.assign(context, {\n [setCurrentQueryParamsKey]: setCurrentQueryParams,\n })) as unknown as CraftQueryParamOutputs<\n Context,\n StoreConfig,\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >;\n}\n\nexport function serializeQueryParams<\n QueryParamsState extends Record<string, unknown>,\n QueryParamsConfig extends {\n state: Record<string, QueryParamConfig<unknown>>;\n },\n>(params: QueryParamsState, queryParamsConfig: QueryParamsConfig) {\n const queryParamsObject = Object.entries(params).reduce(\n (acc, [key, value]) => {\n const paramConfig = queryParamsConfig.state[key];\n if (paramConfig && value !== undefined) {\n acc[key] = paramConfig.serialize(value);\n }\n return acc;\n },\n {} as Record<string, string>,\n );\n\n const result = Object.defineProperty(queryParamsObject, 'toString', {\n value() {\n return serializedQueryParamsObjectToString(this);\n },\n enumerable: false, // 👈 ne s'affichera pas dans les clés\n });\n return result;\n}\n\nexport function serializedQueryParamsObjectToString(\n queryParamsObject: Record<string, unknown>,\n) {\n return Object.entries(queryParamsObject)\n .map(\n ([key, value]) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(value as string)}`,\n )\n .join('&');\n}\n","import { Injector, isSignal, Signal } from '@angular/core';\nimport {\n ContextConstraints,\n ContextInput,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n MergeTwoContexts,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { capitalize } from './util/util';\nimport { QueryParamConfig, QueryParamOutput } from './query-param';\nimport { UnionToTuple } from './util//types/util.type';\nimport {\n serializeQueryParams,\n SpecificCraftQueryParamOutputs,\n} from './craft-query-param';\n\ntype ToSpecificCraftQueryParamsOutputs<\n QueryParamKeysTuple,\n QueryParams,\n Acc extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints\n> = QueryParamKeysTuple extends [infer Head, ...infer Tail]\n ? Head extends keyof QueryParams\n ? QueryParams[Head] extends QueryParamOutput<\n infer QueryParamsType,\n infer Insertions,\n infer QueryParamsState\n >\n ? SpecificCraftQueryParamOutputs<\n Head & string,\n QueryParamsType,\n Insertions,\n QueryParamsState\n > extends infer Current\n ? Current extends ContextConstraints\n ? ToSpecificCraftQueryParamsOutputs<\n Tail,\n QueryParams,\n MergeTwoContexts<Acc, Current>,\n StoreConfig\n >\n : never\n : never\n : PartialContext<{\n _error: {\n message: `Typing Error: QueryParams '${Head &\n string}' value is not a QueryParamsOutput - store: [${StoreConfig['name']}]`;\n };\n }>\n : Acc\n : Acc;\n\nexport type SpecificCraftQueryParamsOutputs<\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>,\n StoreConfig extends StoreConfigConstraints\n> = ToSpecificCraftQueryParamsOutputs<\n UnionToTuple<QueryParamKeys>,\n QueryParams,\n PartialContext<{}>,\n StoreConfig\n>;\n\ntype SpecificCraftQueryStandaloneOutputs<\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>\n> = {\n [K in QueryParamKeys as `set${Capitalize<\n K & string\n >}QueryParam`]: QueryParams[K] extends QueryParamOutput<\n unknown,\n unknown,\n infer QueryParamsState\n >\n ? <\n T extends Partial<{\n [StateKey in keyof QueryParamsState]: QueryParamsState[StateKey];\n }>\n >(\n params: T\n ) => {\n [StateKey in keyof T]: string;\n }\n : never;\n};\n\ntype CraftQueryParamsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftQueryParamsOutputs<QueryParamKeys, QueryParams, StoreConfig>,\n SpecificCraftQueryStandaloneOutputs<QueryParamKeys, QueryParams>\n>;\n\n/**\n * Creates a craft factory for managing multiple reactive query parameter groups integrated with the craft store.\n *\n * This function allows you to define multiple named query parameter groups within a single craft store by:\n * - Creating typed signals for each query parameter group prefixed with their respective names\n * - Providing standalone methods to serialize query params for navigation outside injection context\n * - Synchronizing all query parameter groups with URL query parameters automatically\n *\n * @remarks\n * **Important:** The `queryParamFactory` function must return an object where each value is a `queryParam()` call.\n * Since `queryParam()` requires an injection context, `craftQueryParams` handles this by:\n * - Calling the factory within an injection context to create the reactive query param managers\n * - Calling the factory outside injection context to extract configurations for standalone methods\n *\n * **Warning:** Be careful to avoid query params key collisions between different groups. (There is no verification yet)\n *\n * @param queryParamFactory - Factory function that receives craft context and returns an object of QueryParamOutput instances\n * @returns A craft factory function with standalone methods for serializing each query param group\n *\n * @example\n * Basic usage with multiple query param groups\n * ```ts\n * const { injectCraft, setPaginationQueryParam, setActiveQueryParam } = craft(\n * {\n * providedIn: 'root',\n * name: 'myStore',\n * },\n * craftQueryParams(() => ({\n * pagination: queryParam({\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * }, ({ set, reset }) => ({ set, reset })),\n * active: queryParam({\n * state: {\n * isActive: {\n * fallbackValue: false,\n * parse: (value: string) => value === 'true',\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * }, ({ set, reset }) => ({ set, reset })),\n * }))\n * );\n *\n * // In a component (injection context):\n * const store = injectCraft();\n *\n * // Accessing query param values\n * store.paginationPage(); // Signal<number> for 'page' from pagination group\n * store.paginationPageSize(); // Signal<number> for 'pageSize' from pagination group\n * store.pagination(); // Signal<{ page: number; pageSize: number }>\n * store.activeIsActive(); // Signal<boolean> for 'isActive' from active group\n * store.active(); // Signal<{ isActive: boolean }>\n *\n * // Updating query param values (also updates URL)\n * store.setPagination({ page: 2, pageSize: 20 });\n * store.setActive({ isActive: true });\n * store.resetPagination();\n * store.resetActive();\n * ```\n *\n * @example\n * Using standalone methods for navigation outside injection context\n * ```ts\n * // Outside injection context (e.g., in a route resolver, guard, or service method):\n * async navigateToMyPage() {\n * await router.navigate(['my-page'], {\n * queryParams: {\n * ...setPaginationQueryParam({ page: 4, pageSize: 20 }),\n * ...setActiveQueryParam({ isActive: true }),\n * },\n * });\n * }\n *\n * navigateByUrlToMyPage() {\n * const paginationParams = setPaginationQueryParam({ page: 4, pageSize: 20 });\n * const activeParams = setActiveQueryParam({ isActive: true });\n * router.navigateByUrl(\n * `/my-page?${paginationParams}&${activeParams}`\n * );\n * }\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const { injectCraft } = craft(\n * {\n * providedIn: 'root',\n * name: 'myStore',\n * },\n * craftQueryParams(() => ({\n * pagination: queryParam(\n * {\n * state: {\n * page: { fallbackValue: 1, parse: parseInt, serialize: String },\n * },\n * },\n * ({ state, set }) => ({\n * goToPage: (newPage: number) => {\n * set({ ...state(), page: newPage });\n * },\n * })\n * ),\n * filters: queryParam({\n * state: {\n * search: { fallbackValue: '', parse: String, serialize: String },\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n * store.goToPagePagination(5); // Custom method from pagination insertion\n * store.filtersSearch(); // Signal<string> for 'search' from filters group\n * ```\n */\nexport function craftQueryParams<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>\n>(\n queryParamFactory: (context: CraftFactoryEntries<Context>) => QueryParams\n): CraftQueryParamsOutputs<Context, StoreConfig, QueryParamKeys, QueryParams> {\n const context = (\n contextData: ContextInput<Context>,\n injector: Injector,\n _storeConfig: StoreConfig,\n _cloudProxy: Context['_cloudProxy']\n ) => {\n console.log('contextData', contextData);\n const queryParamStates = queryParamFactory(\n craftFactoryEntries(contextData)\n );\n\n const { props, methods } = Object.entries(queryParamStates).reduce(\n (acc, [key, queryParam]) => {\n const { props, methods } = Object.entries(\n queryParam as QueryParamOutput<unknown, unknown, unknown>\n ).reduce(\n (acc, [queryParamKey, queryParamValue]) => {\n if (isSignal(queryParamValue)) {\n (acc.props as Record<string, Signal<any>>)[\n `${key}${capitalize(queryParamKey)}`\n ] = queryParamValue;\n } else {\n (acc.methods as Record<string, Function>)[\n `${queryParamKey}${capitalize(key)}`\n ] = queryParamValue as Function;\n }\n return acc;\n },\n { props: {}, methods: {} } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n }\n );\n\n Object.assign(acc.props, props);\n Object.assign(acc.methods, methods);\n\n return acc;\n },\n { props: {}, methods: {} } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n }\n );\n\n return partialContext({\n props: { ...props, ...queryParamStates },\n _queryParams: Object.entries(queryParamStates).reduce(\n (acc, [key, queryParam]) => {\n acc[key] = {\n config: queryParam,\n state: queryParam,\n };\n return acc;\n },\n {} as Record<string, { config: unknown; state: unknown }>\n ),\n methods,\n }) as SpecificCraftQueryParamsOutputs<\n QueryParamKeys,\n QueryParams,\n StoreConfig\n >;\n };\n\n // when queryParam is called outside the injection context, it will only return the config\n const queryParamsConfigs = queryParamFactory({});\n\n const setQueryParams = Object.entries(queryParamsConfigs).reduce(\n (acc, [key, queryParam]) => {\n const setCurrentQueryParams = (params: Record<string, unknown>) => {\n return serializeQueryParams(\n params,\n (queryParam as QueryParamOutput<unknown, unknown, unknown>)\n ._config as { state: Record<string, QueryParamConfig<unknown>> }\n );\n };\n const setCurrentQueryParamsKey = `set${capitalize(key)}QueryParam`;\n acc[setCurrentQueryParamsKey] = setCurrentQueryParams;\n return acc;\n },\n {} as Record<string, Function>\n );\n\n return (() =>\n Object.assign(\n context,\n setQueryParams\n )) as unknown as CraftQueryParamsOutputs<\n Context,\n StoreConfig,\n QueryParamKeys,\n QueryParams\n >;\n}\n","import { MergeObject, MergeObjects } from './util/util.type';\nimport {\n ContextConstraints,\n CraftFactoryUtility,\n StoreConfigConstraints,\n PartialContext,\n craftFactoryEntries,\n partialContext,\n} from './craft';\nimport { ResourceByIdRef } from './resource-by-id';\nimport { QueryOutput, QueryRef } from './query';\n\ntype SpecificCraftQueryOutputs<\n ResourceName extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs,\n> = PartialContext<{\n props: {\n [key in `${ResourceName & string}`]: QueryOutput<\n ResourceState,\n ResourceArgsParams,\n ResourceParams,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >;\n };\n _query: {\n [key in ResourceName & string]: QueryOutput<\n ResourceState,\n ResourceArgsParams,\n ResourceParams,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >;\n };\n}>;\n\ntype CraftQueryOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n ResourceName extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftQueryOutputs<\n ResourceName,\n ResourceState,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >\n>;\n\ntype ContextQueryEntries<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n ResourceName extends string,\n> = Context['_inputs'] &\n Context['_injections'] &\n Context['_sources'] &\n Omit<Context['props'], keyof Context['_mutation']> &\n Context['_AsyncProcess'] &\n Context['_mutation'] & {\n INSERT_CONFIG: {\n storeName: StoreConfig['name'];\n key: NoInfer<ResourceName>;\n };\n };\n\n/**\n * Creates a query definition for use within a craft store, enabling reactive data fetching with automatic state management.\n *\n * This function integrates a `query()` instance into a craft store by:\n * - Registering the query under a specific name in the store\n * - Providing automatic execution when params change\n * - Exposing query state signals (value, status, error, isLoading)\n * - Enabling reactive connections to mutations, sources, and other store entries\n * - Supporting insertions for extended functionality (optimistic updates, persistence, etc.)\n * - Providing type-safe access to query results and methods\n *\n * @remarks\n * **Use Cases:**\n * - **Server state management**: Fetch and cache data from APIs\n * - **Automatic refetching**: Re-fetch when params change reactively\n * - **Optimistic updates**: Update UI instantly while mutations execute\n * - **Cache synchronization**: Keep local cache in sync with server state after mutations\n * - **Data persistence**: Cache query results across sessions\n * - **Loading states**: Track and display loading/error states automatically\n *\n * **Context Access:**\n * The query factory receives full access to the craft context:\n * - Sources: React to user events and triggers\n * - Mutations: Coordinate with mutation state and results\n * - Other queries: Derive data from other queries\n * - Injections: Access Angular services and dependencies\n * - INSERT_CONFIG: Store name and query key for insertions\n *\n * **Reactive Patterns:**\n * - Use `insertReactOnMutation()` to synchronize with mutation results\n * - Bind to sources for manual refetch triggers\n * - Use with identifier for parallel query execution\n * - Combine with `preservePreviousValue` to prevent flickering\n *\n * **Store Integration:**\n * - Query accessible as: `store.queryName`\n * - Returns signals: `store.queryName.value()`, `store.queryName.status()`\n * - With identifier: `store.queryName.select(id)` for individual instances\n * - Custom insertions add methods: `store.queryName.customMethod()`\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template ResourceName - The name of the query (must be a literal string)\n * @template ResourceState - The type of the query result data\n * @template ResourceParams - The type of the query parameters\n * @template ResourceArgsParams - The type of method arguments (for method-based queries)\n * @template InsertionsOutputs - The accumulated outputs from query insertions\n * @template IsMethod - Whether the query uses method-based triggering\n * @template SourceParams - The type of source params (for source-based queries)\n * @template GroupIdentifier - The identifier type (for queries with identifier)\n *\n * @param resourceName - The name under which this query will be registered in the store.\n * Used to access the query: `store.resourceName`\n * @param queryFactory - Factory function that receives the craft context and returns a query() instance.\n * Has access to all other craft entries (sources, mutations, queries, states) defined before it.\n *\n * @returns A craft factory utility that integrates the query into the store with:\n * - `store.queryName`: The query instance with all its signals and methods\n * - Full type safety for query state and operations\n *\n * @example\n * Basic query with automatic execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('currentUser', () =>\n * query({\n * params: () => currentUserId(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access query state\n * console.log(store.currentUser.status()); // 'loading'\n * console.log(store.currentUser.value()); // undefined initially\n *\n * // After loading completes\n * console.log(store.currentUser.status()); // 'resolved'\n * console.log(store.currentUser.value()); // { id: '123', name: 'John', ... }\n * console.log(store.currentUser.isLoading()); // false\n * console.log(store.currentUser.hasValue()); // true\n * ```\n *\n * @example\n * Query with optimistic updates from mutations\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateTodo: mutation({\n * method: (todo: Todo) => todo,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('todos', ({ updateTodo }) =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateTodo, {\n * // Update UI instantly while mutation is loading\n * optimisticUpdate: ({ queryResource, mutationParams }) => {\n * const todos = queryResource.value() ?? [];\n * return todos.map(todo =>\n * todo.id === mutationParams.id ? mutationParams : todo\n * );\n * },\n * // Confirm update when mutation resolves\n * update: ({ queryResource, mutationParams }) => {\n * const todos = queryResource.value() ?? [];\n * return todos.map(todo =>\n * todo.id === mutationParams.id ? mutationParams : todo\n * );\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Update a todo - UI updates immediately (optimistic)\n * store.mutateUpdateTodo({ id: '1', text: 'Updated', done: true });\n * // store.todos.value() already reflects the change\n * ```\n *\n * @example\n * Query with patch-based updates\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateEmail: mutation({\n * method: (data: { userId: string; email: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}/email`, {\n * method: 'PATCH',\n * body: JSON.stringify({ email: params.email }),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('user', ({ updateEmail }) =>\n * query(\n * {\n * params: () => currentUserId(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateEmail, {\n * // Patch only the email field\n * optimisticPatch: {\n * email: ({ mutationParams }) => mutationParams.email,\n * },\n * patch: {\n * email: ({ mutationParams }) => mutationParams.email,\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Only email field is updated, rest of user data unchanged\n * store.mutateUpdateEmail({ userId: '123', email: 'new@example.com' });\n * ```\n *\n * @example\n * Query with reload on mutation events\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * createPost: mutation({\n * method: (data: CreatePostData) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * deletePost: mutation({\n * method: (postId: string) => ({ postId }),\n * loader: async ({ params }) => {\n * await fetch(`/api/posts/${params.postId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * }),\n * })),\n * craftQuery('posts', ({ createPost, deletePost }) =>\n * query(\n * {\n * params: () => ({ page: 1 }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts?page=${params.page}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(createPost, {\n * reload: { onMutationResolved: true }, // Reload after create\n * }),\n * insertReactOnMutation(deletePost, {\n * reload: { onMutationResolved: true }, // Reload after delete\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Posts list automatically reloads after create/delete\n * store.mutateCreatePost({ title: 'New Post', content: '...' });\n * // -> posts query reloads automatically when mutation completes\n * ```\n *\n * @example\n * Query with identifier for parallel execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('userDetails', () =>\n * query({\n * params: () => selectedUserId(),\n * identifier: (userId) => userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access specific user instances\n * const user1 = store.userDetails.select('user-1');\n * const user2 = store.userDetails.select('user-2');\n *\n * console.log(user1?.status()); // 'resolved'\n * console.log(user1?.value()); // { id: 'user-1', name: '...' }\n * console.log(user2?.status()); // 'loading'\n * ```\n *\n * @example\n * Query with streaming data\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('liveCount', () =>\n * query({\n * params: () => ({}),\n * stream: async () => {\n * const resultSignal = signal({ count: 0 });\n *\n * // Simulate streaming updates\n * const interval = setInterval(() => {\n * resultSignal.update(v => ({ count: v.count + 1 }));\n * }, 1000);\n *\n * return resultSignal;\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Value updates continuously as stream emits\n * console.log(store.liveCount.value()); // { count: 5 }\n * // ... after 1 second\n * console.log(store.liveCount.value()); // { count: 6 }\n * ```\n *\n * @example\n * Query with persistence\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('products', () =>\n * query(\n * {\n * params: () => ({ category: currentCategory() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/products?category=${params.category}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'ProductStore',\n * key: 'products',\n * cacheTime: 600000, // 10 minutes\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Products are cached in localStorage\n * // On next visit, cached data loads instantly while fresh data fetches\n * console.log(store.products.value()); // Cached data available immediately\n * ```\n *\n * @example\n * Query reacting to sources\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * refresh: source<void>(),\n * }),\n * craftQuery('data', ({ refresh }) =>\n * query({\n * method: afterRecomputation(refresh, () => ({})),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Query executes automatically when source emits\n * store.setRefresh();\n * // -> data query executes\n * ```\n *\n * @example\n * Complex coordination with multiple mutations and conditional reloads\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateArticle: mutation({\n * method: (data: Article) => data,\n * identifier: (data) => data.id,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/articles/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('articles', ({ updateArticle }) =>\n * query(\n * {\n * params: () => ({ status: 'published' }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/articles?status=${params.status}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateArticle, {\n * // Only reload if the update affects published articles\n * reload: {\n * onMutationResolved: ({ mutationParams }) =>\n * mutationParams.status === 'published',\n * },\n * // Patch the article in the list optimistically\n * optimisticUpdate: ({ queryResource, mutationParams }) => {\n * const articles = queryResource.value() ?? [];\n * return articles.map(article =>\n * article.id === mutationParams.id ? mutationParams : article\n * );\n * },\n * })\n * )\n * )\n * );\n * ```\n */\nexport function craftQuery<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n const ResourceName extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n ResourceArgsParams,\n InsertionsOutputs,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n>(\n resourceName: ResourceName,\n queryFactory: (\n context: ContextQueryEntries<Context, StoreConfig, ResourceName>,\n ) => QueryOutput<\n ResourceState,\n ResourceArgsParams,\n ResourceParams,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >,\n): CraftQueryOutputs<\n Context,\n StoreConfig,\n ResourceName,\n NoInfer<ResourceState>,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n> {\n return () => (contextData, injector, storeConfig) => {\n const queryFactoryContext = craftFactoryEntries(contextData);\n const queryRef = queryFactory({\n ...queryFactoryContext,\n INSERT_CONFIG: {\n storeName: storeConfig.name,\n key: resourceName,\n },\n } as ContextQueryEntries<\n Context,\n StoreConfig,\n ResourceName\n >) as unknown as QueryRef<\n ResourceState,\n ResourceParams,\n ResourceArgsParams,\n InsertionsOutputs,\n IsMethod,\n SourceParams,\n GroupIdentifier\n >;\n\n return partialContext({\n props: {\n [`${resourceName as ResourceName}`]: Object.assign(\n queryRef,\n ) as MergeObject<\n ResourceByIdRef<\n GroupIdentifier & string,\n ResourceState,\n ResourceParams\n >,\n InsertionsOutputs\n >,\n },\n _query: {\n [resourceName as ResourceName]: queryRef,\n },\n }) as SpecificCraftQueryOutputs<\n ResourceName,\n ResourceState,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >;\n };\n}\n","import { WritableSignal } from '@angular/core';\nimport {\n ContextConstraints,\n EmptyContext,\n CraftFactoryUtility,\n StoreConfigConstraints,\n partialContext,\n CloudProxySource,\n} from './craft';\nimport { Prettify } from './util/util.type';\nimport { FlatRecord, STORE_CONFIG_TOKEN } from './util/util.type';\nimport { capitalize } from './util/util';\n\ntype InferQueryParamsState<T> = T extends WritableSignal<infer U> ? U : never;\n\ntype SpecificCraftSetAllQueriesParamsStandaloneOutputs<\n Context extends ContextConstraints,\n> = {\n [K in `setAll${Capitalize<\n (typeof STORE_CONFIG_TOKEN)['NAME']\n >}QueryParams`]: <\n AllQueriesParamsState extends {\n [K in keyof Context['_queryParams']]: 'state' extends keyof Context['_queryParams'][K]\n ? InferQueryParamsState<Context['_queryParams'][K]['state']>\n : 'STORE_CONFIG_ERROR: When using craftSetAllQueriesParamsStandalone, each query param configuration must define a state';\n },\n >(\n params: Prettify<AllQueriesParamsState>,\n ) => {\n [K in keyof FlatRecord<AllQueriesParamsState>]: string;\n };\n};\n\ntype CraftSetAllQueriesParamsStandaloneOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n EmptyContext,\n SpecificCraftSetAllQueriesParamsStandaloneOutputs<Context>\n>;\n\n/**\n * Creates a standalone method to set all query parameters at once for use in Angular Router navigation.\n *\n * This function generates a utility method that:\n * - Collects query parameter state from all registered query params in the store\n * - Serializes all values into URL-compatible strings\n * - Returns a flat object compatible with Angular Router's `queryParams` option\n * - Provides a `toString()` method for use with `navigateByUrl()`\n * - Enables type-safe batch updates of all query parameters\n *\n * @remarks\n * **Use Cases:**\n * - **Programmatic navigation**: Set all query params when navigating to a route\n * - **Link generation**: Create URLs with all current query parameter state\n * - **Deep linking**: Generate shareable URLs with complete state\n * - **Bulk updates**: Update multiple query param groups in one operation\n *\n * **Naming Convention:**\n * - Generated method: `setAll{StoreName}QueryParams`\n * - Example: For store named \"MyStore\", method is `setAllMyStoreQueryParams`\n *\n * **Router Integration:**\n * - Use with `router.navigate(['/path'], { queryParams: result })`\n * - Use with `router.navigateByUrl(`/path?${result}`)`\n * - Compatible with `routerLink` directive\n *\n * **Type Safety:**\n * - Input is typed based on all registered query param configurations\n * - Output is a flat record of string values ready for the URL\n * - TypeScript ensures all required query param groups are provided\n *\n * **Requirements:**\n * - Must be used after all `craftQueryParam()` definitions in the craft store\n * - Each query param must define a `state` with parse/serialize/fallbackValue\n *\n * @template Context - The craft store context type containing all query param definitions\n * @template StoreConfig - The craft store configuration type with store name\n *\n * @returns A craft factory utility that adds a standalone method:\n * `setAll{StoreName}QueryParams(params)` - Accepts object with all query param states,\n * returns flat string record for router + toString() method for URL construction\n *\n * @example\n * Basic usage with router.navigate\n * ```ts\n * const { injectCraft, setAllMyStoreQueryParams } = craft(\n * { name: 'MyStore', providedIn: 'root' },\n * craftQueryParam('pagination', () =>\n * queryParam({\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (v) => parseInt(v, 10),\n * serialize: (v) => String(v),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (v) => parseInt(v, 10),\n * serialize: (v) => String(v),\n * },\n * },\n * })\n * ),\n * craftQueryParam('filter', () =>\n * queryParam({\n * state: {\n * search: {\n * fallbackValue: '',\n * parse: (v) => v,\n * serialize: (v) => v,\n * },\n * active: {\n * fallbackValue: false,\n * parse: (v) => v === 'true',\n * serialize: (v) => String(v),\n * },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * // In a component\n * const router = inject(Router);\n *\n * function goToPage(page: number) {\n * router.navigate(['/items'], {\n * queryParams: setAllMyStoreQueryParams({\n * pagination: { page, pageSize: 20 },\n * filter: { search: 'angular', active: true },\n * }),\n * });\n * // URL: /items?page=5&pageSize=20&search=angular&active=true\n * }\n * ```\n *\n * @example\n * Using with navigateByUrl and toString()\n * ```ts\n * const { setAllBlogQueryParams } = craft(\n * { name: 'Blog', providedIn: 'root' },\n * craftQueryParam('sorting', () =>\n * queryParam({\n * state: {\n * sortBy: {\n * fallbackValue: 'date',\n * parse: (v) => v,\n * serialize: (v) => v,\n * },\n * order: {\n * fallbackValue: 'desc' as 'asc' | 'desc',\n * parse: (v) => v as 'asc' | 'desc',\n * serialize: (v) => v,\n * },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * const router = inject(Router);\n *\n * function goToPosts() {\n * const params = setAllBlogQueryParams({\n * sorting: { sortBy: 'title', order: 'asc' },\n * });\n *\n * // Use toString() for navigateByUrl\n * router.navigateByUrl(`/posts?${params}`);\n * // URL: /posts?sortBy=title&order=asc\n * }\n * ```\n *\n * @example\n * Type-safe usage with autocomplete\n * ```ts\n * const { setAllShopQueryParams } = craft(\n * { name: 'Shop', providedIn: 'root' },\n * craftQueryParam('filters', () =>\n * queryParam({\n * state: {\n * category: { fallbackValue: 'all', parse: String, serialize: String },\n * minPrice: { fallbackValue: 0, parse: Number, serialize: String },\n * maxPrice: { fallbackValue: 1000, parse: Number, serialize: String },\n * },\n * })\n * ),\n * craftQueryParam('view', () =>\n * queryParam({\n * state: {\n * layout: { fallbackValue: 'grid', parse: String, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * // TypeScript enforces providing all query param groups\n * const queryParams = setAllShopQueryParams({\n * filters: { category: 'electronics', minPrice: 100, maxPrice: 500 },\n * view: { layout: 'list' },\n * });\n * // ✓ Type-safe: all required groups provided\n *\n * // TypeScript error if missing a group:\n * // const incomplete = setAllShopQueryParams({\n * // filters: { category: 'electronics', minPrice: 100, maxPrice: 500 },\n * // // Error: Property 'view' is missing\n * // });\n * ```\n *\n * @example\n * Generating shareable links\n * ```ts\n * const { injectCraft, setAllArticleQueryParams } = craft(\n * { name: 'Article', providedIn: 'root' },\n * craftQueryParam('reader', () =>\n * queryParam({\n * state: {\n * fontSize: { fallbackValue: 16, parse: Number, serialize: String },\n * theme: { fallbackValue: 'light', parse: String, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * const store = injectCraft();\n *\n * function getShareableLink(): string {\n * const params = setAllArticleQueryParams({\n * reader: {\n * fontSize: store.readerFontSize(),\n * theme: store.readerTheme(),\n * },\n * });\n *\n * return `${window.location.origin}/article/123?${params}`;\n * // Returns: https://example.com/article/123?fontSize=18&theme=dark\n * }\n * ```\n *\n * @example\n * Conditional query param values\n * ```ts\n * const { setAllSearchQueryParams } = craft(\n * { name: 'Search', providedIn: 'root' },\n * craftQueryParam('query', () =>\n * queryParam({\n * state: {\n * q: { fallbackValue: '', parse: String, serialize: String },\n * page: { fallbackValue: 1, parse: Number, serialize: String },\n * },\n * })\n * ),\n * craftQueryParam('advanced', () =>\n * queryParam({\n * state: {\n * dateFrom: { fallbackValue: '', parse: String, serialize: String },\n * dateTo: { fallbackValue: '', parse: String, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * function searchWithFilters(searchTerm: string, useAdvanced: boolean) {\n * const router = inject(Router);\n *\n * router.navigate(['/search'], {\n * queryParams: setAllSearchQueryParams({\n * query: { q: searchTerm, page: 1 },\n * advanced: useAdvanced\n * ? { dateFrom: '2024-01-01', dateTo: '2024-12-31' }\n * : { dateFrom: '', dateTo: '' }, // Use fallback values\n * }),\n * });\n * }\n * ```\n *\n * @example\n * Integration with routerLink directive\n * ```ts\n * // In component class\n * const { setAllProductQueryParams } = craft(\n * { name: 'Product', providedIn: 'root' },\n * craftQueryParam('display', () =>\n * queryParam({\n * state: {\n * view: { fallbackValue: 'grid', parse: String, serialize: String },\n * perPage: { fallbackValue: 12, parse: Number, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * // Generate query params for template\n * listViewParams = setAllProductQueryParams({\n * display: { view: 'list', perPage: 24 },\n * });\n *\n * gridViewParams = setAllProductQueryParams({\n * display: { view: 'grid', perPage: 12 },\n * });\n *\n * // In template\n * // <a [routerLink]=\"['/products']\" [queryParams]=\"listViewParams\">List View</a>\n * // <a [routerLink]=\"['/products']\" [queryParams]=\"gridViewParams\">Grid View</a>\n * ```\n */\nexport function craftSetAllQueriesParamsStandalone<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n>(): CraftSetAllQueriesParamsStandaloneOutputs<Context, StoreConfig> {\n return (_cloudProxy: CloudProxySource, storeConfig) => {\n return Object.assign(() => partialContext({}), {\n [`setAll${capitalize(storeConfig.name)}QueryParams`]: (allQueryParams: {\n [queryParamsName: string]: unknown;\n }) => {\n const { flatParams, queryStringParts } = Object.entries(\n allQueryParams,\n ).reduce(\n (acc, [queryParamsName, params]) => {\n console.log(`Setting query params for ${queryParamsName}:`, params);\n const queryParams = (\n _cloudProxy[\n `set${capitalize(queryParamsName)}QueryParams`\n ] as Function\n )(params as Record<string, unknown>);\n Object.entries(queryParams).forEach(([key, value]) => {\n acc.flatParams[key] = value;\n });\n // Keep the string representation for later\n acc.queryStringParts.push(\n // If queryParams is already something like URLSearchParams-like:\n queryParams.toString(),\n );\n\n return acc;\n },\n {\n flatParams: {} as Record<string, unknown>,\n queryStringParts: [] as string[],\n },\n );\n\n // Define toString only once, after the reduce\n const result = Object.defineProperty(flatParams, 'toString', {\n value() {\n // Join all partial query strings with \"&\"\n return queryStringParts\n .filter((part) => part && part.length > 0)\n .join('&');\n },\n enumerable: false,\n configurable: true,\n writable: true,\n });\n\n return result;\n },\n });\n };\n}\n","import { isSignal } from '@angular/core';\nimport {\n ContextConstraints,\n CraftFactoryUtility,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { SignalSource } from './signal-source';\nimport { Source$ } from './source$';\nimport { capitalize } from './util/util';\n\n// todo handle Observable that are readonly (not Subject...)\n\ntype InferSourceType<S> =\n S extends SignalSource<infer T>\n ? T\n : S extends Source$<infer U>\n ? U\n : S extends _Subscribable<infer V>\n ? V\n : never;\n\ntype PrefixedSourceType<S> =\n S extends SignalSource<infer T>\n ? 'set'\n : S extends Source$<infer U>\n ? 'emit'\n : S extends {\n next: (value: infer V) => void;\n }\n ? 'next'\n : never;\n\nexport type SourceSetterMethods<Sources extends {}> = {\n [K in keyof Sources as `${PrefixedSourceType<Sources[K]>}${Capitalize<string & K>}`]: (\n payload: InferSourceType<Sources[K]>,\n ) => void;\n};\n\ntype SpecificCraftSourcesOutputs<Sources extends {}> = PartialContext<{\n methods: SourceSetterMethods<Sources>;\n _sources: Sources;\n}>;\n\ntype CraftSourcesOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Inputs extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftSourcesOutputs<Inputs>\n>;\n\n// Help to infer RxJs Observable inner type without referencing the library in the types\ninterface _Subscribable<T> {\n subscribe(observer: (value: T) => void): unknown;\n}\n\n/**\n * Creates source definitions for use within a craft store, enabling reactive signal-source-driven communication.\n *\n * `craftSources` integrates source instances into a craft store by:\n * - Registering multiple sources with their names as keys\n * - Automatically generating setter methods with `set` prefix for each source\n * - Providing type-safe access to sources and their setter methods\n * - Enabling reactive patterns where states and queries can react to source emissions\n *\n * @param sourcesFactory - A factory function that returns an object mapping source names to Source instances.\n * Each source can be a SignalSource, Source$, or any Observable-like object.\n * The factory enables sources to be created within Angular's injection context.\n *\n * @returns A craft factory utility that:\n * - Makes sources accessible in context for other craft entries via `context.sourceName`\n * - Adds prefixed setter methods to the store: `store.setSourceName(payload)`\n *\n * @example\n * ```ts\n * const { injectCraft } = craft(\n * { name: 'MyStore', providedIn: 'root' },\n * craftSources(() => ({\n * userAction: source$<string>(),\n * refresh: source$<void>(),\n * })),\n * );\n *\n * const store = injectCraft();\n * store.setUserAction('clicked');\n * ```\n */\nexport function craftSources<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Sources extends Record<\n string,\n SignalSource<any> | Source$<any> | _Subscribable<any>\n >,\n>(\n sourcesFactory: () => Sources, // Return a function enable to run source$ in injection context\n): CraftSourcesOutputs<Context, StoreConfig, Sources> {\n return (() => (contextData: ContextConstraints) => {\n const sources = sourcesFactory();\n const methods = Object.entries(sources).reduce(\n (acc, [key, source]) => {\n const prefix = isSignal(source)\n ? 'set'\n : 'emit' in source\n ? 'emit'\n : 'next' in source\n ? 'next'\n : undefined;\n\n if (!prefix) {\n return acc;\n }\n\n return {\n ...acc,\n [`${prefix}${capitalize(key)}`]: (payload: unknown) => {\n if (isSignal(source)) {\n source.set(payload);\n } else if ('emit' in source) {\n source.emit(payload);\n } else if ('next' in source) {\n //@ts-expect-error next exists on both Subject and EventEmitter but with different types, we need to check which one it is\n source.next(payload);\n }\n },\n };\n },\n {} as Record<string, (payload: unknown) => void>,\n );\n return partialContext({\n _sources: sources,\n methods,\n }) as SpecificCraftSourcesOutputs<Sources>;\n }) as unknown as CraftSourcesOutputs<Context, StoreConfig, Sources>;\n}\n","import {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { StateOutput } from './state';\nimport { isSignal, Signal } from '@angular/core';\nimport { capitalize } from './util/util';\nimport { DeferredExtract } from './util/util.type';\n\ntype SpecificCraftStateOutputs<StateName extends string, State, Insertions> =\n DeferredExtract<Insertions> extends infer Extracted\n ? Extracted extends { props: unknown; methods: Record<string, Function> }\n ? PartialContext<{\n props: {\n [key in StateName]: Signal<State>;\n } & {\n [key in keyof Extracted['props'] as `${StateName &\n string}${Capitalize<key & string>}`]: Extracted['props'][key];\n };\n methods: {\n [key in keyof Extracted['methods'] as `${StateName &\n string}${Capitalize<key & string>}`]: Extracted['methods'][key];\n };\n }>\n : never\n : never;\n\ntype CraftStateOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n StateName extends string,\n State,\n Insertions,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftStateOutputs<StateName, State, Insertions>\n>;\n\n/**\n * Creates a state definition for use within a craft store, enabling reactive state management with optional custom methods and computed values.\n *\n * This function integrates a `state()` instance into a craft store by:\n * - Registering the state under a specific name in the store\n * - Automatically prefixing custom methods and computed values with the state name\n * - Providing type-safe access to state, methods, and computed properties\n * - Enabling reactive connections to sources, inputs, and other store states\n * - Supporting insertions for extended functionality\n *\n * @remarks\n * **Naming Convention:**\n * - The state is accessible as `store.stateName` (returns the Signal)\n * - Custom methods are prefixed: `store.stateNameMethodName`\n * - Computed values are prefixed: `store.stateNameComputedName`\n *\n * **Use Cases:**\n * - **Local UI state**: Form values, filters, pagination, modal visibility\n * - **Derived state**: Computed values based on state changes\n * - **Coordinated state**: State that reacts to other states or sources\n * - **Encapsulated logic**: State with associated behavior methods\n *\n * **Integration:**\n * - Access to other craft entries (sources, queries, mutations) via context\n * - Can react to sources using `afterRecomputation()`\n * - Supports all state() insertion features (persistence, validation, etc.)\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template StateName - The name of the state (must be a literal string)\n * @template State - The type of the state value\n * @template Insertions - The accumulated outputs from state insertions\n *\n * @param stateName - The name under which this state will be registered in the store.\n * Used as prefix for all methods and computed values.\n * @param stateFactory - Factory function that receives the craft context and returns a state() instance.\n * Has access to all other craft entries (sources, queries, mutations, states) defined before it.\n *\n * @returns A craft factory utility that integrates the state into the store with:\n * - `store.stateName`: Signal returning the current state value\n * - `store.stateNameMethodName`: Prefixed custom methods from insertions\n * - `store.stateNameComputedName`: Prefixed computed signals from insertions\n *\n * @example\n * Basic state without methods\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('counter', () => state(0))\n * );\n *\n * const store = injectCraft();\n *\n * // Access the state\n * console.log(store.counter()); // 0\n *\n * // Update the state\n * store.counter.set(5);\n * console.log(store.counter()); // 5\n * ```\n *\n * @example\n * State with custom methods\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('todos', () =>\n * state(\n * [] as Todo[],\n * ({ state, set }) => ({\n * add: (todo: Todo) => {\n * set([...state(), todo]);\n * },\n * remove: (id: string) => {\n * set(state().filter(t => t.id !== id));\n * },\n * clear: () => {\n * set([]);\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Use prefixed methods\n * store.todosAdd({ id: '1', text: 'Buy milk', done: false });\n * store.todosAdd({ id: '2', text: 'Walk dog', done: false });\n * console.log(store.todos().length); // 2\n *\n * store.todosRemove('1');\n * console.log(store.todos().length); // 1\n *\n * store.todosClear();\n * console.log(store.todos().length); // 0\n * ```\n *\n * @example\n * State with computed values\n * ```ts\n * const { injectCraft } = craft(\n * { name: 'CartStore', providedIn: 'root' },\n * craftState('items', () =>\n * state(\n * [] as CartItem[],\n * ({ state, set }) => ({\n * add: (item: CartItem) => {\n * set([...state(), item]);\n * },\n * // Computed values are also prefixed\n * count: computed(() => state().length),\n * total: computed(() =>\n * state().reduce((sum, item) => sum + item.price * item.quantity, 0)\n * ),\n * isEmpty: computed(() => state().length === 0),\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access computed values with prefixed names\n * console.log(store.itemsCount()); // 0\n * console.log(store.itemsIsEmpty()); // true\n *\n * store.itemsAdd({ id: '1', name: 'Book', price: 15, quantity: 2 });\n * console.log(store.itemsCount()); // 1\n * console.log(store.itemsTotal()); // 30\n * console.log(store.itemsIsEmpty()); // false\n * ```\n *\n * @example\n * State reacting to sources\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * resetFilters: source<void>(),\n * }),\n * craftState('filters', ({ resetFilters }) =>\n * state(\n * { search: '', category: 'all', priceRange: [0, 1000] },\n * ({ state, set }) => ({\n * setSearch: (search: string) => {\n * set({ ...state(), search });\n * },\n * setCategory: (category: string) => {\n * set({ ...state(), category });\n * },\n * // React to source to reset state\n * reset: afterRecomputation(resetFilters, () => {\n * set({ search: '', category: 'all', priceRange: [0, 1000] });\n * }),\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Use the state\n * store.filtersSetSearch('laptop');\n * store.filtersSetCategory('electronics');\n * console.log(store.filters()); // { search: 'laptop', category: 'electronics', ... }\n *\n * // Reset via source\n * store.setResetFilters();\n * console.log(store.filters()); // { search: '', category: 'all', ... }\n * ```\n *\n * @example\n * State coordinating with multiple sources\n * ```ts\n * const globalReset = source<string>();\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * localReset: source<string>(),\n * }),\n * craftState('pageState', ({ localReset }) =>\n * state(\n * { page: 1, items: [] as string[] },\n * ({ state, set }) => ({\n * addItem: (item: string) => {\n * set({ ...state(), items: [...state().items, item] });\n * },\n * nextPage: () => {\n * set({ ...state(), page: state().page + 1 });\n * },\n * // React to local source\n * localReset: afterRecomputation(localReset, (reason) => {\n * console.log('Local reset:', reason);\n * set({ page: 1, items: [] });\n * }),\n * // React to global source\n * globalReset: afterRecomputation(globalReset, (reason) => {\n * console.log('Global reset:', reason);\n * set({ page: 1, items: ['default'] });\n * }),\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * store.pageStateAddItem('item1');\n * store.pageStateAddItem('item2');\n * console.log(store.pageState().items); // ['item1', 'item2']\n *\n * store.setLocalReset('User action');\n * console.log(store.pageState().items); // []\n *\n * globalReset.set('System reset');\n * console.log(store.pageState().items); // ['default']\n * ```\n *\n * @example\n * State with persistence\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('preferences', () =>\n * state(\n * { theme: 'light', language: 'en', notifications: true },\n * insertLocalStoragePersister({\n * storeName: 'SettingsStore',\n * key: 'preferences',\n * cacheTime: Number.POSITIVE_INFINITY, // Never expire\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Preferences are automatically persisted and restored\n * store.preferences.set({ theme: 'dark', language: 'fr', notifications: false });\n * // On next app load, preferences are automatically restored\n * ```\n *\n * @example\n * Multiple states in one store\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('ui', () =>\n * state({ sidebarOpen: false, modalOpen: false })\n * ),\n * craftState('user', () =>\n * state({ isAuthenticated: false, userId: null as string | null })\n * ),\n * craftState('notifications', () =>\n * state([] as Notification[])\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access different states\n * console.log(store.ui()); // { sidebarOpen: false, modalOpen: false }\n * console.log(store.user()); // { isAuthenticated: false, userId: null }\n * console.log(store.notifications()); // []\n *\n * // Update independently\n * store.ui.set({ sidebarOpen: true, modalOpen: false });\n * store.user.set({ isAuthenticated: true, userId: 'user-123' });\n * ```\n */\nexport function craftState<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n const StateName extends string,\n State,\n Insertions,\n>(\n stateName: StateName,\n stateFactory: (\n context: CraftFactoryEntries<Context>,\n ) => StateOutput<State, Insertions>,\n): CraftStateOutputs<Context, StoreConfig, StateName, State, Insertions> {\n return () => (contextData) => {\n const stateResult = stateFactory(craftFactoryEntries(contextData));\n\n const { props, methods } = Object.entries(stateResult).reduce(\n (acc, [key, value]) => {\n if (isSignal(value)) {\n (acc.props as Record<string, Signal<any>>)[\n `${stateName}${capitalize(key)}`\n ] = value;\n } else {\n (acc.methods as Record<string, Function>)[\n `${stateName}${capitalize(key)}`\n ] = value;\n }\n return acc;\n },\n {\n props: {},\n methods: {},\n } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n },\n );\n return partialContext({\n props: { [stateName]: stateResult, ...props },\n methods,\n }) as unknown as SpecificCraftStateOutputs<StateName, State, Insertions>;\n };\n}\n","// Not optimized for performance\nexport function isEqual<T>(a: T, b: T): boolean {\n return replaceEqualDeep(a, b) === a;\n}\n\n// Copied From https://github.dev/TanStack/query\n/**\n * This function returns `a` if `b` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between JSON values for example.\n */\nexport function replaceEqualDeep<T>(a: unknown, b: T): T;\nexport function replaceEqualDeep(a: any, b: any): any {\n if (a === b) {\n return a;\n }\n\n const array = isPlainArray(a) && isPlainArray(b);\n\n if (array || (isPlainObject(a) && isPlainObject(b))) {\n const aItems = array ? a : Object.keys(a);\n const aSize = aItems.length;\n const bItems = array ? b : Object.keys(b);\n const bSize = bItems.length;\n const copy: any = array ? [] : {};\n const aItemsSet = new Set(aItems);\n\n let equalItems = 0;\n\n for (let i = 0; i < bSize; i++) {\n const key = array ? i : bItems[i];\n if (\n ((!array && aItemsSet.has(key)) || array) &&\n a[key] === undefined &&\n b[key] === undefined\n ) {\n copy[key] = undefined;\n equalItems++;\n } else {\n copy[key] = replaceEqualDeep(a[key], b[key]);\n if (copy[key] === a[key] && a[key] !== undefined) {\n equalItems++;\n }\n }\n }\n\n return aSize === bSize && equalItems === aSize ? a : copy;\n }\n\n return b;\n}\n\nfunction isPlainArray(value: unknown) {\n return Array.isArray(value) && value.length === Object.keys(value).length;\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\n// eslint-disable-next-line @typescript-eslint/no-wrapper-object-types\nfunction isPlainObject(o: any): o is Object {\n if (!hasObjectPrototype(o)) {\n return false;\n }\n\n // If has no constructor\n const ctor = o.constructor;\n if (ctor === undefined) {\n return true;\n }\n\n // If has modified prototype\n const prot = ctor.prototype;\n if (!hasObjectPrototype(prot)) {\n return false;\n }\n\n // If constructor does not have an Object-specific method\n\n // eslint-disable-next-line no-prototype-builtins\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false;\n }\n\n // Handles Objects created by Object.create(<arbitrary prototype>)\n if (Object.getPrototypeOf(o) !== Object.prototype) {\n return false;\n }\n\n // Most likely a plain Object\n return true;\n}\n\nfunction hasObjectPrototype(o: any): boolean {\n return Object.prototype.toString.call(o) === '[object Object]';\n}\n","import {\n CreateEffectOptions,\n EffectCleanupRegisterFn,\n EffectRef,\n effect,\n untracked,\n} from '@angular/core';\n// from https://github.com/ngxtension/ngxtension-platform\n\n/**\n * We want to have the Tuple in order to use the types in the function signature\n */\nexport type ExplicitEffectValues<T> = {\n [K in keyof T]: () => T[K];\n};\n\n/**\n * Extend the regular set of effect options\n */\ndeclare interface CreateExplicitEffectOptions extends CreateEffectOptions {\n /**\n * Option that allows the computation not to execute immediately, but only run on first change.\n */\n defer?: boolean;\n}\n\n/**\n * This explicit effect function will take the dependencies and the function to run when the dependencies change.\n *\n * @example\n * ```typescript\n * import { explicitEffect } from 'ngxtension/explicit-effect';\n *\n * const count = signal(0);\n * const state = signal('idle');\n *\n * explicitEffect([count, state], ([count, state], cleanup) => {\n * console.log('count updated', count, state);\n *\n * cleanup(() => {\n * console.log('cleanup');\n * });\n * });\n * ```\n *\n * @param deps - The dependencies that the effect will run on\n * @param fn - The function to run when the dependencies change\n * @param options - The options for the effect with the addition of defer (it allows the computation to run on first change, not immediately)\n */\nexport function explicitEffect<\n Input extends readonly unknown[],\n Params = Input,\n>(\n deps: readonly [...ExplicitEffectValues<Input>],\n fn: (deps: Params, onCleanup: EffectCleanupRegisterFn) => void,\n options?: CreateExplicitEffectOptions | undefined,\n): EffectRef {\n let defer = options && options.defer;\n return effect((onCleanup) => {\n const depValues = deps.map((s) => s());\n untracked(() => {\n if (!defer) {\n fn(depValues as any, onCleanup);\n }\n defer = false;\n });\n }, options);\n}\n","import {\n effect,\n EffectCleanupRegisterFn,\n EffectRef,\n InjectionToken,\n Injector,\n} from '@angular/core';\nimport { explicitEffect, ExplicitEffectValues } from '../explicit-effect';\n\nexport const DYNAMIC_EFFECT_REF_INSTANCE_TOKEN = new InjectionToken<EffectRef>(\n 'Injection token used to provide a dynamically created effectRef instance.',\n);\n\nexport function nestedEffect<T, R, GroupIdentifier extends string>(\n parentInjector: Injector,\n effectFn: (onCleanup: EffectCleanupRegisterFn) => void,\n) {\n const injector = Injector.create({\n providers: [\n {\n provide: DYNAMIC_EFFECT_REF_INSTANCE_TOKEN,\n useFactory: () => {\n return effect(effectFn, {\n injector: parentInjector,\n });\n },\n },\n ],\n parent: parentInjector,\n });\n const effectRef = injector.get(DYNAMIC_EFFECT_REF_INSTANCE_TOKEN);\n return effectRef;\n}\n\nexport function explicitNestedEffect<\n T,\n R,\n GroupIdentifier extends string,\n Input extends readonly unknown[],\n Params = Input,\n>(\n parentInjector: Injector,\n deps: readonly [...ExplicitEffectValues<Input>],\n fn: (deps: Params, onCleanup: EffectCleanupRegisterFn) => void,\n) {\n const injector = Injector.create({\n providers: [\n {\n provide: DYNAMIC_EFFECT_REF_INSTANCE_TOKEN,\n useFactory: () => {\n return explicitEffect(deps, fn, {\n injector: parentInjector,\n });\n },\n },\n ],\n parent: parentInjector,\n });\n const effectRef = injector.get(DYNAMIC_EFFECT_REF_INSTANCE_TOKEN);\n return effectRef;\n}\n","import {\n effect,\n inject,\n Injector,\n linkedSignal,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { isEqual } from './util/persister.util';\nimport {\n PersistedQuery,\n PersistedQueryById,\n QueriesPersister,\n} from './util/persister.type';\nimport { nestedEffect } from './util/types/util';\nimport { ResourceByIdRef } from './resource-by-id';\n\nexport function localStoragePersister(prefix: string): QueriesPersister {\n const _injector = inject(Injector);\n const queriesMap = signal(\n new Map<string, PersistedQuery & { storageKey: string }>(),\n {\n equal: () => false,\n }\n );\n\n const queriesByIdMap = signal(\n new Map<string, PersistedQueryById & { storageKey: string }>(),\n {\n equal: () => false,\n }\n );\n\n const newQueryKeysForNestedEffect = linkedSignal<\n any,\n { newKeys: string[] } | undefined\n >({\n source: queriesMap,\n computation: (currentSource, previous) => {\n if (!currentSource || !Array.from(currentSource.keys()).length) {\n return undefined;\n }\n\n const currentKeys = Array.from(currentSource.keys());\n const previousKeys = Array.from(previous?.source?.keys() || []);\n // Find keys that exist in current but not in previous\n const newKeys = currentKeys.filter(\n (key) => !previousKeys.includes(key)\n ) as string[];\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n });\n\n effect(() => {\n if (!newQueryKeysForNestedEffect()?.newKeys) {\n return;\n }\n\n newQueryKeysForNestedEffect()?.newKeys.forEach((newKey) => {\n const data = untracked(() => queriesMap().get(newKey));\n nestedEffect(_injector, () => {\n if (!data) {\n return;\n }\n const { queryResource, queryResourceParamsSrc, storageKey } = data;\n const queryStatus = queryResource.status();\n const queryValue = queryResource.value(); // also track the query value, because the status can stayed local but the value may change\n\n if (queryStatus !== 'resolved' && queryStatus !== 'local') {\n return;\n }\n untracked(() => {\n const queryParams = queryResourceParamsSrc();\n localStorage.setItem(\n storageKey,\n JSON.stringify({\n queryParams,\n queryValue,\n timestamp: Date.now(),\n })\n );\n });\n });\n\n if (data?.waitForParamsSrcToBeEqualToPreviousValue) {\n const waitForParamsSrcToBeEqualToPreviousValueEffect = nestedEffect(\n _injector,\n () => {\n const { queryResourceParamsSrc, storageKey, queryResource } = data;\n const params = queryResourceParamsSrc();\n if (params === undefined) {\n return;\n }\n const storedValue = localStorage.getItem(storageKey);\n if (!storedValue) {\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n try {\n const { queryValue, queryParams, timestamp } =\n JSON.parse(storedValue);\n\n // Check if cache is expired\n if (\n timestamp &&\n data.cacheTime > 0 &&\n isValueExpired(timestamp, data.cacheTime)\n ) {\n localStorage.removeItem(storageKey);\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n\n const isEqualParams = isEqual(params, queryParams);\n if (!isEqualParams) {\n localStorage.removeItem(storageKey);\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n if (isEqualParams) {\n queryResource.set(queryValue);\n }\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n }\n );\n }\n });\n });\n\n const newQueryByIdKeysForNestedEffect = linkedSignal<\n any,\n { newKeys: string[] } | undefined\n >({\n source: queriesByIdMap,\n computation: (currentSource, previous) => {\n if (!currentSource || !Array.from(currentSource.keys()).length) {\n return undefined;\n }\n\n const currentKeys = Array.from(currentSource.keys());\n const previousKeys = Array.from(previous?.source?.keys() || []);\n const newKeys = currentKeys.filter(\n (key) => !previousKeys.includes(key)\n ) as string[];\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n });\n\n effect(() => {\n if (!newQueryByIdKeysForNestedEffect()?.newKeys) {\n return;\n }\n\n // Each time their is a status change in the queryById resource it will save the query with only the resource that are 'resolved' or 'local' (it may be improved)\n newQueryByIdKeysForNestedEffect()?.newKeys.forEach((newKey) => {\n const data = untracked(() => queriesByIdMap().get(newKey));\n nestedEffect(_injector, () => {\n if (!data) {\n return;\n }\n\n const { queryByIdResource, queryResourceParamsSrc, storageKey } = data;\n\n const newRecordInQueryByIdForNestedEffect = linkedSignal<\n any,\n { newKeys: string[] } | undefined\n >({\n source: queryByIdResource,\n computation: (\n currentSource: ReturnType<\n ResourceByIdRef<string, unknown, unknown>\n >,\n previous\n ) => {\n if (!currentSource || !Object.keys(currentSource).length) {\n return undefined;\n }\n\n const currentKeys = Object.keys(currentSource);\n const previousKeys = Array.from(previous?.source?.keys() || []);\n const newKeys = currentKeys.filter(\n (key) => !previousKeys.includes(key)\n ) as string[];\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n });\n newRecordInQueryByIdForNestedEffect()?.newKeys.forEach((newRecord) => {\n const data = untracked(() => queryByIdResource()[newRecord]);\n nestedEffect(_injector, () => {\n if (!data) {\n return;\n }\n\n let storedValue: QueryByIdStored | undefined;\n try {\n storedValue = JSON.parse(\n localStorage.getItem(storageKey) || 'null'\n );\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n localStorage.removeItem(storageKey);\n }\n storedValue = storedValue ?? {\n queryParams: queryResourceParamsSrc(),\n queryByIdValue: {},\n timestamp: Date.now(),\n };\n\n const isStable =\n data.status() === 'resolved' || data.status() === 'local';\n const dataValue = data.hasValue() ? data.value() : undefined;\n untracked(() => {\n storedValue = {\n queryParams: queryResourceParamsSrc(),\n queryByIdValue: {\n ...storedValue?.queryByIdValue,\n [newRecord]: {\n params:\n storedValue?.queryByIdValue[newRecord]?.params ??\n queryResourceParamsSrc(),\n value: dataValue,\n reloadOnMount: !isStable,\n timestamp: Date.now(),\n },\n },\n timestamp: Date.now(),\n };\n localStorage.setItem(storageKey, JSON.stringify(storedValue));\n });\n });\n });\n });\n });\n });\n\n return {\n addQueryToPersist(data: PersistedQuery): void {\n const {\n key,\n queryResource,\n queryResourceParamsSrc,\n waitForParamsSrcToBeEqualToPreviousValue,\n cacheTime,\n } = data;\n\n const storageKey = getStorageKey(prefix, key, 'resource');\n const storedValue = localStorage.getItem(storageKey);\n if (storedValue && !waitForParamsSrcToBeEqualToPreviousValue) {\n try {\n const { queryValue, timestamp } = JSON.parse(storedValue);\n if (\n timestamp &&\n cacheTime > 0 &&\n isValueExpired(timestamp, cacheTime)\n ) {\n localStorage.removeItem(storageKey);\n } else {\n queryResource.set(queryValue);\n }\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n localStorage.removeItem(storageKey);\n }\n }\n queriesMap.update((map) => {\n map.set(key, {\n queryResource,\n queryResourceParamsSrc,\n storageKey,\n waitForParamsSrcToBeEqualToPreviousValue,\n cacheTime,\n key,\n });\n return map;\n });\n },\n\n addQueryByIdToPersist(data: PersistedQueryById): void {\n const { key, queryByIdResource, queryResourceParamsSrc, cacheTime } =\n data;\n\n const storageKey = getStorageKey(prefix, key, 'resourceById');\n let storedValue: QueryByIdStored | undefined;\n try {\n storedValue = JSON.parse(localStorage.getItem(storageKey) || 'null');\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n localStorage.removeItem(storageKey);\n }\n\n const storedValueWithValidCacheTime =\n removeNotValidRecordsWithValidCacheTime(\n storageKey,\n storedValue,\n cacheTime\n );\n if (storedValueWithValidCacheTime) {\n const { queryByIdValue } = storedValueWithValidCacheTime;\n\n if (queryByIdValue && typeof queryByIdValue === 'object') {\n Object.entries(queryByIdValue).forEach(\n ([resourceKey, resourceValue]) => {\n const resourceRef = queryByIdResource.addById(resourceKey, {\n defaultParam: resourceValue.params,\n defaultValue: resourceValue.value,\n });\n // The reload strategy can be improved to prioritize the current displayed resource\n if (resourceValue.reloadOnMount) {\n resourceRef.reload();\n }\n }\n );\n }\n }\n queriesByIdMap.update((map) => {\n map.set(key, {\n queryByIdResource,\n queryResourceParamsSrc,\n storageKey,\n cacheTime,\n key,\n });\n return map;\n });\n },\n\n clearQuery(queryKey: string): void {\n queriesMap.update((map) => {\n map.delete(queryKey);\n localStorage.removeItem(getStorageKey(prefix, queryKey, 'resource'));\n return map;\n });\n },\n\n clearQueryBy(queryByIdKey: string): void {\n queriesByIdMap.update((map) => {\n map.delete(queryByIdKey);\n localStorage.removeItem(\n getStorageKey(prefix, queryByIdKey, 'resourceById')\n );\n return map;\n });\n },\n\n clearAllQueries(): void {\n queriesMap().forEach((_, key) => {\n localStorage.removeItem(getStorageKey(prefix, key, 'resource'));\n });\n queriesMap.update((map) => {\n map.clear();\n return map;\n });\n },\n\n clearAllQueriesById(): void {\n queriesByIdMap().forEach((_, key) => {\n localStorage.removeItem(getStorageKey(prefix, key, 'resourceById'));\n });\n queriesByIdMap.update((map) => {\n map.clear();\n return map;\n });\n },\n clearAllCache(): void {\n this.clearAllQueriesById();\n this.clearAllQueries();\n },\n };\n}\n\ntype QueryByIdStored = {\n queryParams: any;\n queryByIdValue: Record<\n string,\n {\n params: any;\n value: any;\n /**\n * Use it when the resource was loading and didn't finish before the app was closed\n */\n reloadOnMount: boolean;\n timestamp: number;\n }\n >;\n /**\n * Newest timestamp of the stored value\n */\n timestamp: number;\n};\n\nfunction getStorageKey(prefix: string, key: string, type: string) {\n return `ng-craft-${prefix}-${type}-${key}`;\n}\n\nfunction isValueExpired(timestamp: number, cacheTime: number): boolean {\n return Date.now() - timestamp > cacheTime;\n}\n\nfunction removeNotValidRecordsWithValidCacheTime(\n storageKey: string,\n storedValue: QueryByIdStored | undefined,\n cacheTime: number\n): QueryByIdStored | undefined {\n if (!storedValue) {\n return undefined;\n }\n const { queryByIdValue, timestamp } = storedValue;\n\n if (timestamp && cacheTime > 0 && isValueExpired(timestamp, cacheTime)) {\n // remove from storage\n localStorage.removeItem(storageKey);\n return undefined;\n }\n\n const validQueryByIdValue = Object.entries(queryByIdValue).reduce(\n (acc, [key, value]) => {\n const isValueExpiredResult = isValueExpired(value.timestamp, cacheTime);\n if (!isValueExpiredResult) {\n acc[key] = value;\n }\n return acc;\n },\n {} as QueryByIdStored['queryByIdValue']\n );\n\n // update local storage\n localStorage.setItem(\n storageKey,\n JSON.stringify({\n ...storedValue,\n queryByIdValue: validQueryByIdValue,\n })\n );\n\n return {\n ...storedValue,\n queryByIdValue: validQueryByIdValue,\n };\n}\n","import { localStoragePersister } from './local-storage-persister';\nimport {\n InsertionByIdParams,\n InsertionResourceFactoryContext,\n InsertionParams,\n InsertionStateFactoryContext,\n} from './query.core';\nimport { ResourceByIdRef } from './resource-by-id';\nimport { ResourceRef } from '@angular/core';\n\n/**\n * Creates an insertion function that persists resource or state data to localStorage with automatic cache management.\n *\n * This insertion enables automatic persistence and restoration of data across browser sessions, providing:\n * - Automatic saving of query/mutation/state data to localStorage\n * - Restoration of cached data when the application loads\n * - Cache expiration with configurable time-to-live (TTL)\n * - Automatic garbage collection of expired cache entries\n * - Support for both single resources and resources grouped by identifier\n * - Optional waiting for params to stabilize before persisting\n *\n * @remarks\n * **Use Cases:**\n * - **Offline-first applications**: Keep data available when the user goes offline\n * - **Performance optimization**: Show cached data instantly while fetching fresh data\n * - **User experience**: Preserve user's view state across page refreshes\n * - **Reduce server load**: Serve data from cache when it's still fresh\n *\n * **Cache Management:**\n * - Data is stored with a timestamp in localStorage\n * - Expired entries are automatically removed during garbage collection\n * - Each store maintains its own namespace to avoid key collisions\n * - Supports both primitive and complex object serialization\n *\n * **Compatibility:**\n * Works with: `query()`, `mutation()`, `AsyncProcess()`, and `state()`\n *\n * @template GroupIdentifier - The type of identifier for grouped resources (string)\n * @template ResourceState - The type of the resource state (object or undefined)\n * @template ResourceParams - The type of the resource parameters\n * @template PreviousInsertionsOutputs - The accumulated outputs from previous insertions\n * @template StateType - The type of the state (for state() usage)\n * @template CacheTime - The cache time in milliseconds (defaults to 300000 = 5 minutes)\n *\n * @param config - Configuration object:\n * - `storeName`: Prefix for localStorage keys to namespace this store\n * - `key`: Specific key to identify this data within the store\n * - `waitForParamsSrcToBeEqualToPreviousValue` (optional): If true, waits for params to stabilize before persisting.\n * Useful when params can be undefined initially. Default: true\n * - `cacheTime` (optional): Time in milliseconds before cached data is considered stale. Default: 300000 (5 minutes)\n *\n * @returns An insertion function that adds a `persister` property to the resource/state, enabling manual control if needed\n *\n * @example\n * Basic query with localStorage persistence\n * ```ts\n * const userQuery = query(\n * {\n * params: () => ({ userId: currentUserId() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'currentUser',\n * cacheTime: 600000, // 10 minutes\n * })\n * );\n *\n * // On first load, data is fetched from server and cached\n * // On subsequent loads, cached data is shown immediately while fresh data loads in background\n * console.log(userQuery.value()); // Cached data available instantly\n * ```\n *\n * @example\n * Query with identifier for multiple cached instances\n * ```ts\n * const postsQuery = query(\n * {\n * params: () => currentPostId(),\n * identifier: (postId) => postId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts/${params}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'blogApp',\n * key: 'posts',\n * cacheTime: 900000, // 15 minutes\n * })\n * );\n *\n * // Each post is cached individually by its identifier\n * // Cache keys: blogApp:posts:post-123, blogApp:posts:post-456, etc.\n * const post1 = postsQuery.select('post-123');\n * const post2 = postsQuery.select('post-456');\n * ```\n *\n * @example\n * Mutation with persistence for optimistic updates\n * ```ts\n * const updateSettingsMutation = mutation(\n * {\n * method: (settings: UserSettings) => settings,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/settings', {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'userSettings',\n * cacheTime: 86400000, // 24 hours\n * })\n * );\n *\n * // Settings are persisted across sessions\n * // User's preferences survive page refreshes and browser restarts\n * ```\n *\n * @example\n * State persistence for UI preferences\n * ```ts\n * const themeState = state(\n * { mode: 'light', fontSize: 14 } as const,\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'theme',\n * cacheTime: Number.POSITIVE_INFINITY, // Never expire\n * })\n * );\n *\n * // Theme preferences are automatically saved and restored\n * themeState.set({ mode: 'dark', fontSize: 16 });\n * // On next visit, the dark theme is automatically applied\n * ```\n *\n * @example\n * Short-lived cache for frequently changing data\n * ```ts\n * const searchResultsQuery = query(\n * {\n * params: () => ({ query: searchTerm() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/search?q=${params.query}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'searchApp',\n * key: 'results',\n * cacheTime: 60000, // 1 minute - short cache for fresh results\n * })\n * );\n *\n * // Search results are cached briefly to improve UX during navigation\n * // Old results are quickly expired to avoid showing stale data\n * ```\n *\n * @example\n * Waiting for params to stabilize\n * ```ts\n * const userIdSignal = signal<string | undefined>(undefined);\n *\n * const userQuery = query(\n * {\n * params: () => userIdSignal(),\n * loader: async ({ params }) => {\n * if (!params) return undefined;\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'user',\n * waitForParamsSrcToBeEqualToPreviousValue: true, // Wait for userId to be set\n * })\n * );\n *\n * // Persistence waits until userIdSignal has a stable value\n * // Prevents caching with undefined params\n * setTimeout(() => userIdSignal.set('user-123'), 100);\n * ```\n *\n * @example\n * Manual cache control via persister\n * ```ts\n * const dataQuery = query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'data',\n * })\n * );\n *\n * // Access the persister for manual control\n * // Clear this specific cache entry\n * dataQuery.persister.clearCache('data');\n *\n * // Clear all cache entries for this store\n * dataQuery.persister.clearAllCache();\n *\n * // Manually trigger garbage collection\n * dataQuery.persister.runGarbageCollection();\n * ```\n */\nexport function insertLocalStoragePersister<\n GroupIdentifier extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n StateType,\n const CacheTime = 300000, // Default cache time in milliseconds (5 minutes)\n>(config: {\n /** Name of your current store, it is mainly used as a prefix for localStorage keys */\n storeName: string;\n /** Key used to identify the specific data within the store */\n key: string;\n /** Whether to wait for the params source to be equal to its previous value before persisting.\n * Mainly useful when params can be undefined at the beginning. (And for single resource).\n * Default is true.\n */\n waitForParamsSrcToBeEqualToPreviousValue?: boolean;\n /**\n * Default cache time in milliseconds.\n * This is the time after which the cached data will be considered stale and eligible for garbage collection.\n * If not specified, the default is 5 minutes (300000 ms).\n */\n cacheTime?: CacheTime;\n}) {\n return (\n context:\n | InsertionResourceFactoryContext<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >\n | InsertionStateFactoryContext<StateType, PreviousInsertionsOutputs>,\n ) => {\n type ResourceByIdContext = InsertionByIdParams<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >;\n type ResourceContext = InsertionParams<\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >;\n const persister = localStoragePersister(config.storeName);\n const hasResourceById = 'resourceById' in context;\n const isUsingIdentifier =\n hasResourceById ||\n ('identifier' in context &&\n typeof (context as unknown as ResourceByIdContext).identifier ===\n 'function');\n const resourceTarget =\n 'resourceById' in context\n ? context.resourceById\n : 'state' in context\n ? (context as any).state\n : (context as ResourceContext).resource;\n\n if (isUsingIdentifier) {\n persister.addQueryByIdToPersist({\n key: config.key,\n cacheTime: (config?.cacheTime as number | undefined) ?? 300000,\n queryByIdResource: resourceTarget as unknown as ResourceByIdRef<\n string,\n unknown,\n unknown\n >,\n queryResourceParamsSrc: (\n context as ResourceByIdContext | ResourceContext\n ).resourceParamsSrc,\n });\n } else {\n persister.addQueryToPersist({\n key: config.key,\n cacheTime: (config?.cacheTime as number | undefined) ?? 300000,\n queryResource: resourceTarget as unknown as ResourceRef<unknown>,\n queryResourceParamsSrc: (\n context as unknown as ResourceByIdContext | ResourceContext\n ).resourceParamsSrc,\n waitForParamsSrcToBeEqualToPreviousValue: true,\n });\n }\n\n return {\n persister,\n };\n };\n}\n","import { linkedSignal, Signal, ValueEqualityFn, signal } from '@angular/core';\nimport { ReadonlySource } from './util/source.type';\nimport { SignalSource } from './signal-source';\nimport { SourceBranded } from './util/util';\n\nexport function linkedSource<SourceState, ComputedValue>(\n signalOrigin: SignalSource<SourceState> | ReadonlySource<SourceState>,\n computedFn: (sourceValue: NoInfer<SourceState>) => ComputedValue,\n options?: {\n equal?: ValueEqualityFn<NoInfer<ComputedValue> | undefined>;\n debugName?: string;\n },\n): SignalSource<ComputedValue> {\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<SourceState, ComputedValue | undefined>({\n source: signalOrigin as Signal<SourceState>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n return computedFn(currentSourceState);\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n },\n SourceBranded,\n ) as SignalSource<ComputedValue>;\n}\n","import {\n computed,\n isSignal,\n resource,\n ResourceLoaderParams,\n ResourceOptions,\n ResourceRef,\n ResourceStatus,\n ResourceStreamingLoader,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { InsertionsResourcesFactory } from './query.core';\nimport { resourceById, ResourceByIdRef } from './resource-by-id';\nimport { ReadonlySource } from './util/source.type';\nimport { MergeObjects } from './util/util.type';\nimport { CraftResourceRef } from './util/craft-resource-ref';\nimport { craftResource } from './craft-resource';\n// todo refactor to share code with AsyncProcess\n\ntype MutationConfig<\n ResourceState,\n Params,\n ParamsArgs,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n> = Omit<ResourceOptions<NoInfer<ResourceState>, Params>, 'params' | 'loader'> &\n (\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * ! It required One parameter at least to be able to generate the method (otherwise it will think it is bind to a source, see below).\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n *\n * It also accepts a ReadonlySource<SourceParams> to connect the mutation params to an external signal source.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n fromResourceById?: never;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n }\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * ! It required One parameter at least to be able to generate the method (otherwise it will think it is bind to a source, see below).\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n *\n * It also accepts a ReadonlySource<SourceParams> to connect the mutation params to an external signal source.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader?: never;\n fromResourceById?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (entity: ResourceRef<NoInfer<FromObjectState>>) => Params;\n loader?: never;\n method?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (\n entity: CraftResourceRef<\n NoInfer<FromObjectState>,\n NoInfer<FromObjectResourceParams>\n >,\n ) => Params;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n }\n | {\n fromResourceById?: never;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (entity: ResourceRef<NoInfer<FromObjectState>>) => Params;\n loader?: never;\n method?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById?: never;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: () => Params;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n }\n );\n\nexport type ResourceLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n> = {\n type: 'resourceLike';\n kind: 'mutation';\n} & MergeObjects<\n [\n {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n },\n {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n },\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n Insertions,\n {\n [key in `~InternalType`]: 'Used to avoid TS type erasure';\n },\n ]\n>;\n\nexport type ResourceByIdLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier,\n> = { type: 'resourceByGroupLike'; kind: 'mutation' } & {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n} & {\n _resourceById: ResourceByIdRef<GroupIdentifier & string, Value, Params>;\n /**\n * Get the associated resource by id\n *\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n *\n * return the associated resource or undefined if not existing\n */\n select: (id: GroupIdentifier) =>\n | {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n }\n | undefined;\n} & MergeObjects<\n [\n Insertions,\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n ResourceByIdRef<GroupIdentifier & string, Value, Params>,\n ]\n >;\n\nexport type MutationRef<\n Value,\n Params,\n ArgParams,\n Insertions,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n> = [unknown] extends [GroupIdentifier]\n ? ResourceLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions\n >\n : ResourceByIdLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier\n >;\n// & {\n// // ! Otherwise TS erases the types\n// [key in `~InternalType`]: 'Used to avoid TS type erasure';\n// };\n\nexport type MutationOutput<\n State extends object | undefined,\n Params,\n ArgParams,\n SourceParams,\n GroupIdentifier,\n Insertions,\n> = MutationRef<\n State,\n Params,\n ArgParams,\n Insertions,\n [unknown] extends [ArgParams] ? false : true, // ! force to method to have one arg minimum, we can not compare SourceParams type, because it also infer Params\n SourceParams,\n GroupIdentifier\n>;\n\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\n/**\n * Creates a reactive mutation manager that handles asynchronous operations with state tracking.\n *\n * This function manages mutation state by:\n * - Executing asynchronous operations (loader or stream) when triggered\n * - Tracking operation status (idle, loading, resolved, rejected)\n * - Providing reactive signals for value, status, error, and loading state\n * - Supporting both method-based triggers and source-based automatic execution\n * - Optionally enabling parallel mutation execution by grouping instances with an identifier\n *\n * @remarks\n * **Important:** This function must be called within an injection context.\n *\n * **Mutation Modes:**\n * - **Method-based:** Define a `method` function that returns params. Call `mutate()` to trigger the operation.\n * - **Source-based:** Use `afterRecomputation()` to bind to a source signal. The mutation executes automatically when the source changes.\n * - **Resource-based:** Bind to another `ResourceByIdRef` using `fromResourceById` to sync operations.\n *\n * **With Identifier:**\n * When an `identifier` function is provided, mutations are grouped by ID. Use `select(id)` to access individual mutation instances.\n *\n * @param config - Configuration object containing:\n * - `method`: Function that takes args and returns params, or a `ReadonlySource` for automatic execution\n * - `loader`: Async function that performs the mutation and returns a Promise of the result\n * - `stream` (optional): Async function that returns a signal for streaming results\n * - `identifier` (optional): Function to derive a unique ID from params for grouping mutations\n * - `fromResourceById` (optional): Bind to another ResourceByIdRef for synced operations\n * - `params` (optional): Function to derive params from a resource entity\n * - Additional ResourceOptions like `equal`, `injector`, etc.\n * @param insertions - Optional insertion functions to add custom methods, computed values or side effects to the mutation.\n * Insertions receive context with resource signals (`value`, `status`, `error`, `isLoading`, `hasValue`), `config`, and previous insertions.\n * Methods bound to a source using `afterRecomputation` (effectRef-like) are not exposed in the output.\n * @returns A mutation reference object with:\n * - `value`: Signal containing the mutation result (undefined if not yet executed)\n * - `status`: Signal with current status ('idle' | 'loading' | 'resolved' | 'rejected')\n * - `error`: Signal containing any error that occurred\n * - `isLoading`: Signal indicating if the mutation is currently executing\n * - `hasValue()`: Method to check if a value is available\n * - `mutate(args)`: Method to trigger the mutation (only for method-based mutations)\n * - `source`: The connected source (only for source-based mutations)\n * - `select(id)`: Method to access a specific mutation instance by ID (only when identifier is provided)\n * - Custom methods from insertions (excluding methods bound to sources)\n *\n * @example\n * Basic method-based mutation\n * ```ts\n * const updateUser = mutation({\n * method: (userId: string) => ({ userId }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`, { method: 'PATCH' });\n * return response.json();\n * },\n * });\n *\n * // Check status\n * console.log(updateUser.status()); // 'idle'\n * console.log(updateUser.isLoading()); // false\n *\n * // Trigger mutation\n * updateUser.mutate('user-123');\n * console.log(updateUser.status()); // 'loading'\n *\n * // After completion\n * console.log(updateUser.value()); // { id: 'user-123', name: '...' }\n * console.log(updateUser.status()); // 'resolved'\n * ```\n *\n * @example\n * Source-based automatic mutation\n * ```ts\n * todo change example for mutation\n * const updateUserSource = source<{ userId: string, email: string }>();\n *\n * const updateUser = mutation({\n * method: afterRecomputation(updateUserSource, (params) => params),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`, { method: 'PATCH' });\n * return response.json();\n * },\n * });\n *\n * // Mutation executes automatically when source changes\n * updateUserSource.set({ userId: 'user-123', email: 'newemail@example.com' });\n * console.log(updateUser.status()); // 'loading'\n * ```\n *\n * @example\n * Mutation with identifier for grouping\n * ```ts\n * const deleteItem = mutation({\n * method: (itemId: string) => ({ itemId }),\n * identifier: (params) => params.itemId,\n * loader: async ({ params }) => {\n * await fetch(`/api/items/${params.itemId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * });\n *\n * // Trigger mutations for different items\n * deleteItem.mutate('item-1');\n * deleteItem.mutate('item-2');\n *\n * // Access individual mutation states\n * const item1Mutation = deleteItem.select('item-1');\n * console.log(item1Mutation?.status()); // 'loading' or 'resolved'\n * console.log(item1Mutation?.value()); // { deleted: true }\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const createPost = mutation(\n * {\n * method: (data: { title: string; content: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * },\n * ({ value, isLoading }) => ({\n * isSuccess: computed(() => value() !== undefined && !isLoading()),\n * reset: () => {\n * // Custom reset logic\n * },\n * })\n * );\n *\n * createPost.mutate({ title: 'Hello', content: 'World' });\n * console.log(createPost.isSuccess()); // Custom computed from insertion\n * ```\n *\n * @example\n * Binding to another ResourceByIdRef\n * ```ts\n * // First, create a source mutation by ID\n * const fetchUsers = mutation({\n * method: (userId: string) => ({ userId }),\n * identifier: (params) => params.userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json();\n * },\n * });\n *\n * // Then create a derived mutation that processes the results\n * const processedUsers = mutation({\n * fromResourceById: fetchUsers,\n * params: ({ value, status }) => {\n * // Only process when the source is resolved\n * return status() === 'resolved' ? value() : undefined;\n * },\n * identifier: (params) => params.userId,\n * loader: async ({ params }) => {\n * // Process the user data\n * return {\n * ...params,\n * processed: true,\n * timestamp: Date.now(),\n * };\n * },\n * });\n *\n * // Trigger the source mutation\n * fetchUsers.mutate('user-123');\n *\n * // The derived mutation automatically executes when fetchUsers resolves\n * // Access the processed result\n * const processed = processedUsers.select('user-123');\n * console.log(processed?.value()); // { userId: 'user-123', processed: true, ... }\n * ```\n */\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n ...insertions: any[]\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n> {\n const mutationResourceParamsFnSignal =\n //@ts-expect-error if no params, it will create a signal\n mutationConfig.params ?? signal<MutationParams | undefined>(undefined);\n\n const isConnectedToAResourceById = 'fromResourceById' in mutationConfig;\n\n const isConnectedToSource =\n 'method' in mutationConfig && isSignal(mutationConfig.method);\n const isUsingIdentifier = 'identifier' in mutationConfig;\n\n const resourceParamsSrc = isConnectedToSource\n ? mutationConfig.method\n : mutationResourceParamsFnSignal;\n\n const resourceTarget = isUsingIdentifier\n ? resourceById<\n MutationState,\n MutationParams,\n GroupIdentifier & string,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >({\n ...mutationConfig,\n params: resourceParamsSrc,\n identifier: mutationConfig.identifier,\n } as any)\n : craftResource<MutationState, MutationParams>({\n ...mutationConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>);\n\n if (!isUsingIdentifier) {\n Object.assign(resourceTarget, {\n safeValue: computed(() => {\n const resourceRef = resourceTarget as ResourceRef<MutationState>;\n return resourceRef.hasValue() ? resourceRef.value() : undefined;\n }),\n });\n }\n\n return Object.assign(\n resourceTarget,\n // byId is used to helps TS to correctly infer the resourceByGroup\n isUsingIdentifier\n ? {\n /**\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n */\n _resourceById: resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n MutationState,\n MutationParams\n >,\n select: (id: GroupIdentifier) => {\n return computed(() => {\n const list = (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n MutationState,\n MutationParams\n >\n )();\n //@ts-expect-error GroupIdentifier & string is not recognized correctly\n return list[id];\n })();\n },\n }\n : {},\n {\n type: isUsingIdentifier ? 'resourceByGroupLike' : 'resourceLike',\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n MutationParams | undefined\n >,\n mutate:\n isConnectedToAResourceById ||\n ('method' in mutationConfig && isSignal(mutationConfig.method))\n ? undefined\n : (arg: MutationArgsParams) => {\n const result =\n 'method' in mutationConfig\n ? mutationConfig.method?.(arg)\n : undefined;\n // make sure mutationResourceParamsFnSignal.set(result as MutationParams); is set before calling addById\n mutationResourceParamsFnSignal.set(result as MutationParams);\n if (isUsingIdentifier) {\n const id = mutationConfig.identifier?.(arg as any);\n (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n MutationState,\n MutationParams\n >\n ).addById(id as GroupIdentifier & string);\n }\n return result;\n },\n },\n (\n insertions as InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n {}\n >[]\n )?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n ...(isUsingIdentifier\n ? {\n resourceById: resourceTarget,\n identifier: mutationConfig.identifier,\n }\n : { resource: resourceTarget }),\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n NoInfer<MutationParams>\n >,\n insertions: acc as {},\n state: resourceTarget.state,\n set: resourceTarget.set,\n update: resourceTarget.update,\n } as any),\n };\n },\n {} as Record<string, unknown>,\n ),\n ) as unknown as MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n >;\n}\n","import {\n assertInInjectionContext,\n computed,\n inject,\n linkedSignal,\n Signal,\n WritableSignal,\n} from '@angular/core';\nimport {\n InsertionsQueryParamsFactory,\n InsertionQueryParamsFactoryContext,\n} from './query.core';\nimport { MergeObjects } from './util/types/util.type';\nimport { FilterSource, IsEmptyObject } from './util/util.type';\nimport { Prettify } from './util/util.type';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nexport interface QueryParamNavigationOptions {\n queryParamsHandling?: 'merge' | 'preserve' | '';\n onSameUrlNavigation?: 'reload' | 'ignore';\n replaceUrl?: boolean;\n skipLocationChange?: boolean;\n}\n\nexport type QueryParamsToState<QueryParamConfigs> = {\n [K in keyof QueryParamConfigs]: 'parse' extends keyof QueryParamConfigs[K]\n ? QueryParamConfigs[K]['parse'] extends (value: string) => infer U\n ? U\n : 'Error1: QueryParamsToState'\n : 'Error2: QueryParamsToState';\n};\n\nexport type QueryParamOutput<QueryParamsType, Insertions, QueryParamsState> =\n Signal<QueryParamsState> &\n MergeObjects<\n [\n {\n [K in keyof QueryParamsState]: Signal<QueryParamsState[K]>;\n },\n IsEmptyObject<Insertions> extends true ? {} : FilterSource<Insertions>,\n {\n _config: QueryParamsType;\n },\n ]\n >;\n\nexport interface QueryParamConfig<T = unknown> {\n fallbackValue: NoInfer<T>;\n parse: (value: string) => T;\n serialize: (value: NoInfer<T>) => string;\n}\n\n/**\n * Creates a reactive query parameter manager that synchronizes state with URL query parameters.\n *\n * This function manages query parameter state by:\n * - Reading initial values from the URL or using default values\n * - Parsing URL strings into typed values using the provided `parse` function\n * - Serializing typed values back to strings for URL updates using the `serialize` function\n * - Providing reactive signals for each query parameter\n *\n * @remarks\n * **Important:** This function must be called within an injection context.\n * If called outside an injection context, it will only return an object containing the configuration under `_config`.\n *\n * @param config - Configuration object containing:\n * - `state`: Record of query parameter configurations, each with `fallbackValue`, `parse`, and `serialize`\n * - `queryParamsHandling` (optional): How to handle existing query params ('merge' | 'preserve' | '')\n * - `onSameUrlNavigation` (optional): Behavior on same URL navigation ('reload' | 'ignore')\n * - `replaceUrl` (optional): Whether to replace the URL in browser history\n * - `skipLocationChange` (optional): Whether to skip updating the browser's location\n * @param insertions - Optional insertion functions to add custom methods, computed values or side effects to the query param manager.\n * Insertions receive context with `state`, `config`, `set`, `update`, `patch`, `reset` and previous insertions.\n * Methods bound to a source using `afterRecomputation` (effectRef-like) are not exposed in the output.\n * @returns A signal that returns the current query parameter state, extended with:\n * - Individual signals for each query parameter (e.g., `queryParam.page()`)\n * - Custom methods from insertions (excluding methods bound to sources)\n * - `_config`: The original configuration\n *\n * @example\n * Basic usage\n * ```ts\n * const myQueryParams = queryParam(\n * {\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value) => parseInt(value, 10),\n * serialize: (value) => String(value),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (value) => parseInt(value, 10),\n * serialize: (value) => String(value),\n * },\n * },\n * },\n * ({ set, update, patch, reset }) => ({ set, update, patch, reset })\n * );\n *\n * // Access state\n * console.log(myQueryParams()); // { page: 1, pageSize: 10 }\n * console.log(myQueryParams.page()); // 1\n *\n * // Update state (also updates URL)\n * myQueryParams.set({ page: 2, pageSize: 20 });\n * myQueryParams.update(current => ({ ...current, page: current.page + 1 }));\n * myQueryParams.patch({ pageSize: 50 });\n * myQueryParams.reset();\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const myQueryParams = queryParam(\n * {\n * state: {\n * page: { fallbackValue: 1, parse: parseInt, serialize: String },\n * },\n * },\n * ({ state, set }) => ({\n * goTo: (newPage: number) => {\n * set({ ...state(), page: newPage });\n * },\n * })\n * );\n *\n * myQueryParams.goTo(5); // Custom method from insertion\n * ```\n */\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n): QueryParamOutput<QueryParamsType, {}, QueryParamsState>;\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n Insertion1,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n insertion1: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion1\n >,\n): QueryParamOutput<QueryParamsType, Insertion1, QueryParamsState>;\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n Insertion1,\n Insertion2,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n insertion1: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion1\n >,\n insertion2: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion2,\n Insertion1\n >,\n): QueryParamOutput<QueryParamsType, Insertion1 & Insertion2, QueryParamsState>;\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n Insertion1,\n Insertion2,\n Insertion3,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n insertion1: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion1\n >,\n insertion2: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): QueryParamOutput<\n QueryParamsType,\n Insertion1 & Insertion2 & Insertion3,\n QueryParamsState\n>;\n/**\n *\n * If it is not called in an injection context, it returns the config under _config.\n */\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n ...insertions: any[]\n): QueryParamOutput<QueryParamsType, {}, QueryParamsState> {\n try {\n assertInInjectionContext(queryParam);\n } catch (e) {\n return {\n _config: config,\n } as any;\n }\n\n const router = inject(Router);\n const activatedRoute = inject(ActivatedRoute);\n\n const { state: queryParamsConfig, ...options } = config;\n\n // Create signals for each query parameter\n const queryParamFromUrl = linkedSignal(() => {\n return (\n router.currentNavigation()?.extractedUrl.queryParams ??\n activatedRoute.snapshot.queryParams\n );\n });\n\n // Create computed signals for each query parameter with parsing\n const queryParamsState = linkedSignal(() =>\n Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n const rawValue = queryParamFromUrl()?.[key];\n if (rawValue === undefined || rawValue === null) {\n acc[key] = config.fallbackValue;\n return acc;\n }\n try {\n acc[key] = config.parse(rawValue);\n return acc;\n } catch {\n acc[key] = config.fallbackValue;\n return acc;\n }\n },\n {} as Record<string, unknown>,\n ),\n ) as WritableSignal<QueryParamsToState<QueryParamsType>>;\n\n // Get initial values from the url or use the fallback values\n const getDefaultState = () =>\n Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n acc[key] = config.fallbackValue;\n return acc;\n },\n {} as Record<string, unknown>,\n ) as QueryParamsToState<QueryParamsType>;\n\n // Save the original set method before we override it\n const originalSet = queryParamsState.set.bind(queryParamsState);\n\n // Navigation helper\n const navigate = (\n newState: QueryParamsToState<QueryParamsType>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n // Update the local state first using the original set method\n originalSet(newState);\n\n // Then navigate without triggering another update\n const mergedOptions = { ...options, ...navOptions };\n // Only include params that differ from their fallback values (SEO optimization)\n const serializedParams = Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n const currentValue = newState[key];\n // Skip if value equals fallback value\n if (currentValue !== config.fallbackValue) {\n acc[key] = config.serialize(currentValue);\n }\n return acc;\n },\n {} as Record<string, string>,\n );\n\n // Use queueMicrotask to avoid call stack issues\n queueMicrotask(() => {\n router.navigate([], {\n relativeTo: activatedRoute,\n queryParams: serializedParams,\n queryParamsHandling: mergedOptions.queryParamsHandling,\n onSameUrlNavigation: mergedOptions.onSameUrlNavigation,\n replaceUrl: mergedOptions.replaceUrl,\n skipLocationChange: mergedOptions.skipLocationChange,\n });\n });\n };\n\n // Create individual property signals\n const props = Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n acc[key] = computed(() => queryParamsState()[key]);\n return acc;\n },\n {} as Record<string, Signal<unknown>>,\n );\n\n // Create methods\n const methods = {\n set: (\n params: QueryParamsToState<QueryParamsType>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n navigate(params, navOptions);\n },\n update: (\n updateFn: (\n currentParams: QueryParamsToState<QueryParamsType>,\n ) => QueryParamsToState<QueryParamsType>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n const newState = updateFn(queryParamsState());\n navigate(newState, navOptions);\n },\n patch: (\n params: Partial<QueryParamsToState<QueryParamsType>>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n const newState = { ...queryParamsState(), ...params };\n navigate(newState, navOptions);\n },\n reset: (navOptions?: QueryParamNavigationOptions) => {\n navigate(getDefaultState(), navOptions);\n },\n };\n\n // Process insertions\n const insertionResults =\n (insertions as InsertionsQueryParamsFactory<QueryParamsType, {}>[])?.reduce(\n (acc, insert) => {\n const newInsertions = insert({\n state: queryParamsState.asReadonly(),\n config: queryParamsConfig,\n ...methods,\n insertions: acc as {},\n } as InsertionQueryParamsFactoryContext<QueryParamsType, {}>);\n return {\n ...acc,\n ...newInsertions,\n };\n },\n {} as Record<string, unknown>,\n ) || {};\n\n return Object.assign(queryParamsState.asReadonly(), props, insertionResults, {\n _config: config,\n }) as unknown as QueryParamOutput<QueryParamsType, {}, QueryParamsState>;\n}\n","import {\n computed,\n isSignal,\n ResourceLoaderParams,\n ResourceOptions,\n ResourceRef,\n ResourceStatus,\n ResourceStreamingLoader,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { InsertionsResourcesFactory } from './query.core';\nimport { resourceById, ResourceByIdRef } from './resource-by-id';\nimport { ReadonlySource } from './util/source.type';\nimport { MergeObjects } from './util/util.type';\nimport { preservedResource } from './preserved-resource';\nimport { craftResource } from './craft-resource';\n\ntype QueryConfig<\n ResourceState,\n Params,\n ParamsArgs,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n> = Omit<ResourceOptions<NoInfer<ResourceState>, Params>, 'params' | 'loader'> &\n (\n | {\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: () => Params;\n loader: (\n param: NoInfer<ResourceLoaderParams<Params>>,\n ) => Promise<ResourceState>;\n method?: never;\n fromResourceById?: never;\n stream?: never;\n /**\n * Each the query load, the value will return undefined.\n * To avoid flickering display and also enable to the data to be retrieved from cache, use () => true\n * default value: true\n */\n preservePreviousValue?: () => boolean;\n }\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n *\n * It also accepts a ReadonlySource<SourceParams> to connect the query params to an external signal source.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader: (\n param: NoInfer<ResourceLoaderParams<Params>>,\n ) => Promise<ResourceState>;\n params?: never;\n fromResourceById?: never;\n stream?: never;\n preservePreviousValue?: () => boolean;\n }\n | {\n method?: never;\n loader?: never;\n params?: () => Params;\n fromResourceById?: never;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<ResourceState, Params>;\n preservePreviousValue?: () => boolean;\n }\n | {\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader?: never;\n params?: never;\n fromResourceById?: never;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<ResourceState, Params>;\n preservePreviousValue?: () => boolean;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (entity: ResourceRef<NoInfer<FromObjectState>>) => Params;\n loader: (\n param: NoInfer<ResourceLoaderParams<Params>>,\n ) => Promise<ResourceState>;\n method?: never;\n stream?: never;\n /**\n * Each the query load, the value will return undefined.\n * To avoid flickering display and also enable to the data to be retrieved from cache, use () => true\n * default value: true\n */\n preservePreviousValue?: () => boolean;\n }\n | {\n method?: never;\n loader?: never;\n params?: () => Params;\n fromResourceById?: never;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<ResourceState, Params>;\n preservePreviousValue?: () => boolean;\n }\n ) & {\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Under the hood, a resource is generated for each new identifier generated when the params source change.\n *\n * If the source change, and their is an existing resource with the same identifier, it will be re-used.\n *\n * In this case, when the source is an object, an existing resource can be retrieved by the matching his record key with identifier function, but as the reference change it will trigger the loading of the resource again.\n *\n * To avoid this, you can use this option to tell how to compare the incoming params with the existing params of the resource.\n * - 'useIdentifier': will use the identifier function to compare the previous params and the incoming params. This very useful when using pagination.\n * - 'default' (default value): will use a strict equality check (===) between the previous params and the incoming params.\n * - (a: Params, b: Params) => boolean: you can provide your own comparison function to compare the previous params and the incoming params. This is useful when you want to compare specific fields of the params.\n *\n * Note: if your params is a primitive (string, number, boolean, etc.), you don't need to use this option since the strict equality check will work as expected.\n *\n * For **query** that use 'identifier', the default value is 'useIdentifier'\n *\n * For **query** that don't use 'identifier', the default value is 'default'\n */\n equalParams?: Params extends object\n ?\n | 'default'\n | 'useIdentifier'\n | ((\n a: Params,\n b: Params,\n identifierFn: (params: Params) => GroupIdentifier,\n ) => boolean)\n : never;\n };\n\nexport type ResourceLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n> = {\n type: 'resourceLike';\n kind: 'query';\n} & MergeObjects<\n [\n {\n readonly value: Signal<Value | undefined>;\n /**\n * Avoids to throw error when accessing value during error state\n */\n readonly safeValue: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n hasValue(): boolean;\n },\n {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n },\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n Insertions,\n {\n [key in `~InternalType`]: 'Used to avoid TS type erasure';\n },\n ]\n>;\n\nexport type ResourceByIdLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier,\n> = { type: 'resourceByGroupLike'; kind: 'query' } & {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n} & {\n _resourceById: ResourceByIdRef<GroupIdentifier & string, Value, Params>;\n /**\n * Get the associated resource by id\n *\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n *\n * return the associated resource or undefined if not existing\n */\n select: (id: GroupIdentifier) =>\n | {\n readonly value: Signal<Value | undefined>;\n /**\n * Avoids to throw error when accessing value during error state\n */\n readonly safeValue: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n hasValue(): boolean;\n }\n | undefined;\n} & MergeObjects<\n [\n Insertions,\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n ResourceByIdRef<GroupIdentifier & string, Value, Params>,\n ]\n >;\n\nexport type QueryRef<\n Value,\n Params,\n ArgParams,\n Insertions,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n> = [unknown] extends [GroupIdentifier]\n ? ResourceLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions\n >\n : ResourceByIdLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier\n >;\n\nexport type QueryOutput<\n State extends object | undefined,\n Params,\n ArgParams,\n SourceParams,\n GroupIdentifier,\n Insertions,\n> = QueryRef<\n State,\n Params,\n ArgParams,\n Insertions,\n [unknown] extends [ArgParams] ? false : true, // ! force to method to have one arg minimum, we can not compare SourceParams type, because it also infer Params\n SourceParams,\n GroupIdentifier\n>;\n\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\n/**\n * Creates a reactive query manager that handles data fetching with automatic state tracking.\n *\n * This function manages query state by:\n * - Executing asynchronous fetch operations (loader or stream) automatically when params change\n * - Tracking operation status (idle, loading, resolved, rejected)\n * - Providing reactive signals for value, status, error, and loading state\n * - Supporting both params-based automatic execution and method-based manual triggers\n * - Optionally enabling parallel query execution by grouping instances with an identifier\n * - Caching and reusing query results based on params\n *\n * @remarks\n * **Important:** This function must be called within an injection context.\n *\n * **Query Modes:**\n * - **Params-based (automatic):** Define a `params` function. The query executes automatically when params change.\n * - **Method-based (manual):** Define a `method` function that returns params. Call `mutate()` to trigger execution.\n * - **Source-based (reactive):** Bind to a `ReadonlySource` for automatic execution when the source changes.\n * - **Resource-based (derived):** Bind to another `ResourceByIdRef` using `fromResourceById` to create derived queries.\n *\n * **With Identifier:**\n * When an `identifier` function is provided, queries are grouped by ID enabling parallel execution and individual result tracking.\n * Use `select(id)` to access individual query instances.\n *\n * **Caching & Performance:**\n * - Use `preservePreviousValue: () => true` to prevent flickering by keeping previous data while loading\n * - Use `equalParams` to control when queries should re-execute based on params comparison\n *\n * @param config - Configuration object containing:\n * - `params`: Function that returns params for automatic execution, or undefined for method-based queries\n * - `method`: Function that takes args and returns params for manual execution, or a `ReadonlySource` for reactive execution\n * - `loader`: Async function that performs the query and returns a Promise of the result\n * - `stream` (optional): Async function that returns a signal for streaming results\n * - `identifier` (optional): Function to derive a unique ID from params for grouping queries\n * - `fromResourceById` (optional): Bind to another ResourceByIdRef for derived queries\n * - `preservePreviousValue` (optional): Function returning boolean to keep previous value while reloading\n * - `equalParams` (optional): Controls params comparison ('default' | 'useIdentifier' | custom function)\n * - Additional ResourceOptions like `equal`, `injector`, etc.\n * @param insertions - Optional insertion functions to add custom methods, computed values or side effects to the query.\n * Insertions receive context with resource signals (`value`, `status`, `error`, `isLoading`, `hasValue`), `config`, and previous insertions.\n * @returns A query reference object with:\n * - `value`: Signal containing the query result (undefined if not yet executed)\n * - `status`: Signal with current status ('idle' | 'loading' | 'resolved' | 'rejected')\n * - `error`: Signal containing any error that occurred\n * - `isLoading`: Signal indicating if the query is currently executing\n * - `hasValue()`: Method to check if a value is available\n * - `mutate(args)`: Method to trigger the query manually (only for method-based queries)\n * - `source`: The connected source (only for source-based queries)\n * - `select(id)`: Method to access a specific query instance by ID (only when identifier is provided)\n * - `resourceParamsSrc`: The underlying params signal\n * - Custom methods from insertions\n *\n * @example\n * Basic params-based automatic query\n * ```ts\n * const userIdSignal = signal('user-123');\n *\n * const userQuery = query({\n * params: () => userIdSignal(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Query executes automatically when created and when userIdSignal changes\n * console.log(userQuery.status()); // 'loading'\n * // After completion\n * console.log(userQuery.value()); // { id: 'user-123', name: '...' }\n * console.log(userQuery.status()); // 'resolved'\n *\n * // Changing the signal triggers a new query\n * userIdSignal.set('user-456');\n * ```\n *\n * @example\n * Method-based manual query\n * ```ts\n * const searchQuery = query({\n * method: (searchTerm: string) => ({ term: searchTerm }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/search?q=${params.term}`);\n * return response.json();\n * },\n * });\n *\n * // Query doesn't execute automatically\n * console.log(searchQuery.status()); // 'idle'\n *\n * // Manually trigger the query\n * searchQuery.mutate('angular');\n * console.log(searchQuery.status()); // 'loading'\n * ```\n *\n * @example\n * Query with identifier for parallel execution\n * ```ts\n * const userDetailsQuery = query({\n * params: () => currentUserId(),\n * identifier: (userId) => userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Multiple users can be queried in parallel\n * // Each has its own state tracked by identifier\n * const user1 = userDetailsQuery.select('user-1');\n * const user2 = userDetailsQuery.select('user-2');\n *\n * console.log(user1?.status()); // 'resolved'\n * console.log(user1?.value()); // { id: 'user-1', ... }\n * console.log(user2?.status()); // 'loading'\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const todosQuery = query(\n * {\n * params: () => ({ completed: showCompleted() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos?completed=${params.completed}`);\n * return response.json();\n * },\n * },\n * ({ value, isLoading }) => ({\n * count: computed(() => value()?.length ?? 0),\n * isEmpty: computed(() => !isLoading() && value()?.length === 0),\n * })\n * );\n *\n * console.log(todosQuery.count()); // Custom computed from insertion\n * console.log(todosQuery.isEmpty()); // true/false\n * ```\n *\n * @example\n * Streaming query\n * ```ts\n * const liveDataQuery = query({\n * params: () => ({ channel: currentChannel() }),\n * stream: async ({ params }) => {\n * const response = await fetch(`/api/stream/${params.channel}`);\n *\n * // Return a signal that updates as stream data arrives\n * const resultSignal = signal([]);\n * const reader = response.body?.getReader();\n * // ... process stream and update resultSignal\n * return resultSignal;\n * },\n * });\n *\n * // value() updates continuously as stream data arrives\n * ```\n *\n * @example\n * Derived query from another ResourceByIdRef\n * ```ts\n * // First query fetches basic user data\n * const usersQuery = query({\n * params: () => currentUserId(),\n * identifier: (userId) => userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Derived query enriches user data with additional info\n * const enrichedUsersQuery = query({\n * fromResourceById: usersQuery,\n * params: ({ value, status }) => {\n * // Only process when source is resolved\n * return status() === 'resolved' ? value() : undefined;\n * },\n * identifier: (user) => user.id,\n * loader: async ({ params }) => {\n * // Fetch additional data for the user\n * const response = await fetch(`/api/users/${params.id}/details`);\n * const details = await response.json();\n * return { ...params, ...details };\n * },\n * });\n *\n * // Derived query executes automatically when usersQuery resolves\n * const enrichedUser = enrichedUsersQuery.select('user-123');\n * console.log(enrichedUser?.value()); // { ...userData, ...details }\n * ```\n */\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n ...insertions: any[]\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n> {\n const hasParamsFn = typeof queryConfig.method === 'function';\n const queryResourceParamsFnSignal =\n queryConfig.params ?? signal<QueryParams | undefined>(undefined);\n\n const isConnectedToSource = isSignal(queryConfig.method);\n const isUsingIdentifier = 'identifier' in queryConfig;\n\n const resourceParamsSrc = isConnectedToSource\n ? queryConfig.method\n : queryResourceParamsFnSignal;\n\n const resourceTarget = isUsingIdentifier\n ? resourceById<\n QueryState,\n QueryParams,\n GroupIdentifier & string,\n string,\n unknown,\n unknown\n >({\n ...queryConfig,\n params: resourceParamsSrc,\n identifier: queryConfig.identifier,\n equalParams: queryConfig.equalParams ?? 'useIdentifier',\n } as any)\n : !queryConfig.preservePreviousValue || queryConfig.preservePreviousValue()\n ? preservedResource<QueryState, QueryParams>({\n ...queryConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>)\n : craftResource<QueryState, QueryParams>({\n ...queryConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>);\n\n const queryOutputWithoutInsertions = Object.assign(\n resourceTarget,\n // byId is used to helps TS to correctly infer the resourceByGroup\n isUsingIdentifier\n ? {\n /**\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n */\n _resourceById: resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n QueryState,\n QueryParams\n >,\n select: (id: GroupIdentifier) => {\n return computed(() => {\n const list = (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n QueryState,\n QueryParams\n >\n )();\n //@ts-expect-error GroupIdentifier & string is not recognized correctly\n return list[id];\n })();\n },\n }\n : {},\n {\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n QueryParams | undefined\n >,\n method:\n hasParamsFn || isSignal(queryConfig.method)\n ? undefined\n : (arg: QueryArgsParams) => {\n const result = (\n queryConfig.method as unknown as (\n args: QueryArgsParams,\n ) => QueryParams\n )(arg);\n if (isUsingIdentifier) {\n const id = queryConfig.identifier?.(arg as any);\n (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n QueryState,\n QueryParams\n >\n ).addById(id as GroupIdentifier & string);\n }\n //@ts-expect-error if method is exposed params can not be of type (entity: ResourceRef<NoInfer<FromObjectState>>) => QueryParams\n queryResourceParamsFnSignal.set(result as QueryParams);\n return result;\n },\n },\n );\n\n return Object.assign(\n queryOutputWithoutInsertions,\n (\n insertions as InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n {}\n >[]\n )?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n ...(isUsingIdentifier\n ? {\n resourceById: resourceTarget,\n identifier: queryConfig.identifier,\n }\n : { resource: resourceTarget }),\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n NoInfer<QueryParams>\n >,\n insertions: acc as {},\n state: resourceTarget.state,\n set: resourceTarget.set,\n update: resourceTarget.update,\n } as any), // try to improve the type here\n };\n },\n {} as Record<string, unknown>,\n ),\n ) as unknown as QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n >;\n}\n","import { linkedSignal, Signal, signal, ValueEqualityFn } from '@angular/core';\nimport { SourceBranded } from './util/util';\n\nexport type SignalSource<T> = Signal<T | undefined> & {\n set: (value: T) => void;\n preserveLastValue: Signal<T | undefined>;\n} & SourceBranded;\n\n/**\n * Creates a source for event-driven communication with lazy emission semantics.\n *\n * Sources are the foundation of event-driven patterns in ng-craft, enabling:\n * - Discrete event emissions (unlike continuous signals)\n * - Lazy behavior (undefined until explicitly set)\n * - Decoupled communication between components and stores\n * - Automatic triggering of queries, mutations, and async methods\n * - Multi-listener support with independent subscription timing\n *\n * @remarks\n * **Core Concept:**\n * Sources implement event emitter pattern with reactive semantics:\n * - Emit only when explicitly set (not on every read like signals)\n * - Listeners receive `undefined` on first read (lazy semantics)\n * - New listeners don't receive previous emissions by default\n * - Use `preserveLastValue` to get the last emitted value immediately\n *\n * **Difference from Signals:**\n * - **Signals**: Always have a value, recompute on access, continuous state\n * - **Sources**: Emit on explicit set, lazy by default, discrete events\n * - Sources are for events/actions, signals are for state\n *\n * **Use Cases:**\n * - **User actions**: Button clicks, form submissions, custom events\n * - **Navigation events**: Route changes, tab switches\n * - **Data events**: Reload triggers, refresh requests\n * - **Coordination**: Communication between disconnected components\n * - **Store inputs**: Triggering queries/mutations from components\n * - **Event buses**: Decoupled event communication\n *\n * **Integration with Queries/Mutations:**\n * - Bind to method using `afterRecomputation(source, callback)`\n * - Query/mutation executes automatically when source emits\n * - No manual method exposed (source-based triggering)\n *\n * **Listener Semantics:**\n * - **Standard listener**: Returns `undefined` until source emits, then returns new values only\n * - **preserveLastValue**: Returns last emitted value immediately, then tracks new values\n * - Useful for late subscribers that need current state\n *\n * **Limitations:**\n * Sources are signals and behave differently from observables.\n * Understanding these three key limitations is important:\n * - **Multiple sets in same cycle**: When a source is set multiple times during the same cycle\n * (between the first set and the Change Detection that executes all consumer callbacks),\n * consumers will only react once during CD and will only see the last set value.\n * Intermediate values are discarded.\n * - **Multiple sources order**: Within the same cycle, if multiple sources are triggered,\n * consumers cannot determine the order in which the sources were set.\n * The original emission sequence is not preserved.\n * - **Consumer execution order**: When multiple sources are triggered in the same cycle,\n * consumer callbacks are invoked in the order they were declared, not in the order\n * their source producers were triggered.\n * - **No synchronous intermediate value reactions**: Unlike observables, sources cannot react\n * to each intermediate value synchronously. A mechanism similar to observables\n * (or using native Observable API) without RxJS is being considered to enable\n * synchronous reactions to intermediate values, matching the behavior currently\n * offered by observables.\n *\n * @template T - The type of values emitted by the source\n *\n * @param options - Optional configuration:\n * - `equal`: Custom equality function for change detection (prevents duplicate emissions)\n * - `debugName`: Name for debugging purposes\n *\n * @returns A source object with:\n * - `()`: Read current value (undefined until first emission)\n * - `set(value)`: Emit a value to all listeners\n * - `preserveLastValue`: Alternative signal that returns last value immediately\n *\n * @example\n * Basic source for user actions\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * loadUser: source<string>(),\n * }),\n * craftQuery('user', ({ loadUser }) =>\n * query({\n * method: afterRecomputation(loadUser, (userId) => userId),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Query executes automatically when source emits\n * store.setLoadUser('user-123');\n * // -> loadUser source emits 'user-123'\n * // -> user query executes with params 'user-123'\n *\n * store.setLoadUser('user-456');\n * // -> user query executes again with params 'user-456'\n * ```\n *\n * @example\n * Source for form submission\n * ```ts\n * type FormData = { name: string; email: string };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * submitForm: source<FormData>(),\n * }),\n * craftMutations(({ submitForm }) => ({\n * submit: mutation({\n * method: afterRecomputation(submitForm, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // In component template:\n * // <form (submit)=\"onSubmit()\">\n * // <input name=\"name\" [(ngModel)]=\"formData.name\" />\n * // <input name=\"email\" [(ngModel)]=\"formData.email\" />\n * // </form>\n *\n * onSubmit() {\n * // Mutation executes automatically\n * this.store.setSubmitForm(this.formData);\n * // -> submitForm source emits\n * // -> submit mutation executes\n * }\n * ```\n *\n * @example\n * Source for reload/refresh actions\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * reload: source<void>(),\n * }),\n * craftQuery('data', ({ reload }) =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * },\n * insertReloadOnSource(reload)\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Trigger reload from anywhere\n * store.setReload();\n * // -> reload source emits\n * // -> query reloads\n *\n * // In component:\n * // <button (click)=\"store.setReload()\">Refresh</button>\n * ```\n *\n * @example\n * Multiple sources for different actions\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * addTodo: source<{ text: string }>(),\n * deleteTodo: source<string>(),\n * toggleTodo: source<string>(),\n * }),\n * craftMutations(({ addTodo, deleteTodo, toggleTodo }) => ({\n * create: mutation({\n * method: afterRecomputation(addTodo, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/todos', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * delete: mutation({\n * method: afterRecomputation(deleteTodo, (id) => id),\n * loader: async ({ params }) => {\n * await fetch(`/api/todos/${params}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * }),\n * toggle: mutation({\n * method: afterRecomputation(toggleTodo, (id) => id),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos/${params}/toggle`, {\n * method: 'PATCH',\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Different actions trigger different mutations\n * store.setAddTodo({ text: 'Buy milk' });\n * store.setToggleTodo('todo-123');\n * store.setDeleteTodo('todo-456');\n * ```\n *\n * @example\n * Late listener with preserveLastValue\n * ```ts\n * const mySource = source<string>();\n *\n * // Early listener\n * const listener1 = computed(() => mySource());\n * console.log(listener1()); // undefined\n *\n * // Emit value\n * mySource.set('Hello');\n * console.log(listener1()); // 'Hello'\n *\n * // Late listener (after emission)\n * const listener2 = computed(() => mySource());\n * console.log(listener2()); // undefined (doesn't get previous emission)\n *\n * mySource.set('World');\n * console.log(listener1()); // 'World'\n * console.log(listener2()); // 'World'\n *\n * // Using preserveLastValue for late listeners\n * const listener3 = computed(() => mySource.preserveLastValue());\n * console.log(listener3()); // 'World' (gets last value immediately)\n * ```\n *\n * @example\n * Custom equality to prevent duplicate emissions\n * ```ts\n * type Params = { id: string; timestamp: number };\n *\n * const paramsSource = source<Params>({\n * equal: (a, b) => a?.id === b?.id, // Compare only by id\n * });\n *\n * const listener = computed(() => paramsSource());\n *\n * paramsSource.set({ id: 'item-1', timestamp: Date.now() });\n * // -> listener receives value\n *\n * paramsSource.set({ id: 'item-1', timestamp: Date.now() });\n * // -> listener does NOT receive value (same id)\n *\n * paramsSource.set({ id: 'item-2', timestamp: Date.now() });\n * // -> listener receives value (different id)\n * ```\n *\n * @example\n * Source for coordinating multiple components\n * ```ts\n * // Global source (outside component)\n * const refreshAllSource = source<void>();\n *\n * // Component A\n * @Component({\n * selector: 'app-data-view',\n * template: '...',\n * })\n * export class DataViewComponent {\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('data', () =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * },\n * insertReloadOnSource(refreshAllSource)\n * )\n * )\n * );\n *\n * store = this.injectCraft();\n * }\n *\n * // Component B\n * @Component({\n * selector: 'app-refresh-button',\n * template: '<button (click)=\"refresh()\">Refresh All</button>',\n * })\n * export class RefreshButtonComponent {\n * refresh() {\n * // Triggers refresh in all components listening to this source\n * refreshAllSource.set();\n * }\n * }\n * ```\n *\n * @example\n * Source with complex payload\n * ```ts\n * type SearchParams = {\n * query: string;\n * filters: string[];\n * page: number;\n * };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * search: source<SearchParams>(),\n * }),\n * craftQuery('results', ({ search }) =>\n * query({\n * method: afterRecomputation(search, (params) => params),\n * loader: async ({ params }) => {\n * const queryString = new URLSearchParams({\n * q: params.query,\n * filters: params.filters.join(','),\n * page: String(params.page),\n * });\n * const response = await fetch(`/api/search?${queryString}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Emit complex search parameters\n * store.setSearch({\n * query: 'angular',\n * filters: ['tutorial', 'advanced'],\n * page: 1,\n * });\n * ```\n */\nexport function signalSource<T>(options?: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n debugName?: string;\n}): SignalSource<T> {\n const sourceState = signal<T | undefined>(undefined, {\n ...(options?.equal && { equal: options?.equal }), // add the equal function here, it may helps to detect changes when using scalar values\n ...(options?.debugName && {\n debugName: options?.debugName + '_sourceState',\n }),\n });\n\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<T, T | undefined>({\n source: sourceState as Signal<T>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n\n return currentSourceState;\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n set: sourceState.set,\n },\n SourceBranded,\n ) as SignalSource<T>;\n}\n","import {\n assertInInjectionContext,\n DestroyRef,\n inject,\n ValueEqualityFn,\n} from '@angular/core';\nimport { SignalSource, signalSource } from './signal-source';\n\nexport type SourceFromEvent<T> = SignalSource<T> & {\n dispose: () => void;\n};\n\n/**\n * Creates a source from DOM events with automatic cleanup on component destruction.\n *\n * This function bridges DOM events with ng-craft's reactive system by:\n * - Converting native DOM events to source emissions\n * - Automatically removing event listeners on component destruction\n * - Supporting optional event payload transformation\n * - Providing manual disposal capability\n * - Enabling event-driven query/mutation triggering\n *\n * @remarks\n * **Automatic Cleanup:**\n * - Event listeners are automatically removed when the injection context is destroyed\n * - Uses Angular's `DestroyRef` for lifecycle management\n * - Manual cleanup available via `dispose()` method\n * - Prevents memory leaks from dangling event listeners\n *\n * **Use Cases:**\n * - **User interactions**: Click, input, scroll, keyboard events\n * - **Window events**: Resize, scroll, focus, online/offline\n * - **Document events**: Visibility changes, custom events\n * - **Media events**: Video/audio play, pause, ended\n * - **Form events**: Submit, change, input\n * - **Custom events**: Application-specific DOM events\n *\n * **Event Transformation:**\n * - Without `computedValue`: Emits the raw event object\n * - With `computedValue`: Transforms event before emission\n * - Useful for extracting specific event properties\n * - Reduces payload size and improves type safety\n *\n * **Integration with Stores:**\n * - Use source in queries/mutations via `afterRecomputation()`\n * - Trigger async operations on DOM events\n * - Coordinate multiple components via event sources\n *\n * **Injection Context:**\n * - Must be called within Angular injection context\n * - Typically called in component constructor or class fields\n * - Uses `assertInInjectionContext()` for safety\n *\n * @template T - The type of the event object\n * @template ComputedValue - The type after optional transformation\n *\n * @param target - The DOM element or event target to listen to.\n * Can be any EventTarget (HTMLElement, Window, Document, etc.)\n *\n * @param eventName - The name of the event to listen for.\n * Standard DOM event names: 'click', 'input', 'scroll', etc.\n *\n * @param options - Optional configuration:\n * - `event`: Event listener options (capture, passive, once, etc.)\n * - `computedValue`: Function to transform event before emission\n * - `source`: Source options (equal, debugName)\n *\n * @returns A source that emits on DOM events with:\n * - All standard source capabilities (set, preserveLastValue)\n * - `dispose()`: Method to manually remove event listener\n * - Automatic cleanup on component destruction\n *\n * @example\n * Basic click event source\n * ```ts\n * @Component({\n * selector: 'app-clicker',\n * template: '<button #btn>Click me</button>',\n * })\n * export class ClickerComponent {\n * @ViewChild('btn', { read: ElementRef }) button!: ElementRef<HTMLButtonElement>;\n *\n * clickSource = sourceFromEvent<MouseEvent>(\n * this.button.nativeElement,\n * 'click'\n * );\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * trackClick: mutation({\n * method: afterRecomputation(this.clickSource, (event) => ({\n * x: event.clientX,\n * y: event.clientY,\n * })),\n * loader: async ({ params }) => {\n * await fetch('/api/track-click', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return { tracked: true };\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n *\n * // Mutation executes automatically on click\n * }\n * ```\n *\n * @example\n * Window scroll event with transformation\n * ```ts\n * @Component({\n * selector: 'app-infinite-scroll',\n * template: '...',\n * })\n * export class InfiniteScrollComponent {\n * scrollSource = sourceFromEvent(window, 'scroll', {\n * computedValue: () => ({\n * scrollY: window.scrollY,\n * scrollHeight: document.documentElement.scrollHeight,\n * clientHeight: window.innerHeight,\n * }),\n * event: { passive: true }, // Optimize performance\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftAsyncProcesses(() => ({\n * checkLoadMore: asyncProcess({\n * method: afterRecomputation(this.scrollSource, (data) => data),\n * loader: async ({ params }) => {\n * const { scrollY, scrollHeight, clientHeight } = params;\n * const nearBottom = scrollY + clientHeight >= scrollHeight - 100;\n *\n * if (nearBottom) {\n * // Load more data\n * const response = await fetch('/api/load-more');\n * return response.json();\n * }\n * return null;\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n * }\n * ```\n *\n * @example\n * Form input event for real-time validation\n * ```ts\n * @Component({\n * selector: 'app-search',\n * template: '<input #searchInput type=\"text\" placeholder=\"Search...\" />',\n * })\n * export class SearchComponent {\n * @ViewChild('searchInput', { read: ElementRef }) input!: ElementRef<HTMLInputElement>;\n *\n * inputSource = sourceFromEvent(this.input.nativeElement, 'input', {\n * computedValue: (event: Event) => {\n * const target = event.target as HTMLInputElement;\n * return target.value;\n * },\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('results', () =>\n * query({\n * method: afterRecomputation(this.inputSource, (term) => term),\n * loader: async ({ params }) => {\n * if (params.length < 3) return [];\n *\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n *\n * // Query executes on input changes\n * }\n * ```\n *\n * @example\n * Window resize event with debouncing\n * ```ts\n * @Component({\n * selector: 'app-responsive',\n * template: '...',\n * })\n * export class ResponsiveComponent {\n * resizeSource = sourceFromEvent(window, 'resize', {\n * computedValue: () => ({\n * width: window.innerWidth,\n * height: window.innerHeight,\n * }),\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('dimensions', () =>\n * state({ width: window.innerWidth, height: window.innerHeight }, {\n * bindSources: {\n * resize: afterRecomputation(this.resizeSource, (data) => data),\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n *\n * // Dimensions state updates on resize\n * }\n * ```\n *\n * @example\n * Custom DOM event\n * ```ts\n * @Component({\n * selector: 'app-custom-events',\n * template: '<div #container></div>',\n * })\n * export class CustomEventsComponent {\n * @ViewChild('container', { read: ElementRef }) container!: ElementRef<HTMLDivElement>;\n *\n * customEventSource = sourceFromEvent<CustomEvent<{ data: string }>>(\n * this.container.nativeElement,\n * 'custom-event',\n * {\n * computedValue: (event) => event.detail.data,\n * }\n * );\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftAsyncProcesses(() => ({\n * handleCustomEvent: asyncProcess({\n * method: afterRecomputation(this.customEventSource, (data) => data),\n * loader: async ({ params }) => {\n * console.log('Custom event data:', params);\n * return { processed: true };\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n *\n * triggerCustomEvent() {\n * const event = new CustomEvent('custom-event', {\n * detail: { data: 'Hello from custom event' },\n * });\n * this.container.nativeElement.dispatchEvent(event);\n * }\n * }\n * ```\n *\n * @example\n * Manual disposal for dynamic elements\n * ```ts\n * @Component({\n * selector: 'app-dynamic',\n * template: '...',\n * })\n * export class DynamicComponent {\n * private clickSource?: SourceFromEvent<MouseEvent>;\n *\n * attachListener(element: HTMLElement) {\n * // Remove previous listener if exists\n * this.clickSource?.dispose();\n *\n * // Attach to new element\n * this.clickSource = sourceFromEvent<MouseEvent>(element, 'click');\n *\n * // Use in store\n * // ...\n * }\n *\n * detachListener() {\n * // Manually remove listener before component destruction\n * this.clickSource?.dispose();\n * this.clickSource = undefined;\n * }\n * }\n * ```\n *\n * @example\n * Multiple event sources for keyboard shortcuts\n * ```ts\n * @Component({\n * selector: 'app-shortcuts',\n * template: '...',\n * })\n * export class ShortcutsComponent {\n * keydownSource = sourceFromEvent(document, 'keydown', {\n * computedValue: (event: KeyboardEvent) => ({\n * key: event.key,\n * ctrlKey: event.ctrlKey,\n * shiftKey: event.shiftKey,\n * altKey: event.altKey,\n * }),\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftAsyncProcesses(() => ({\n * handleShortcut: asyncProcess({\n * method: afterRecomputation(this.keydownSource, (data) => data),\n * loader: async ({ params }) => {\n * // Handle Ctrl+S\n * if (params.ctrlKey && params.key === 's') {\n * // Save action\n * return { action: 'save' };\n * }\n * // Handle Ctrl+Z\n * if (params.ctrlKey && params.key === 'z') {\n * // Undo action\n * return { action: 'undo' };\n * }\n * return null;\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n * }\n * ```\n */\nexport function sourceFromEvent<T>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: never;\n source: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n debugName?: string;\n };\n },\n): SourceFromEvent<T>;\nexport function sourceFromEvent<T, ComputedValue>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue: (event: T) => ComputedValue;\n source?: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n debugName?: string;\n };\n },\n): SourceFromEvent<ComputedValue>;\nexport function sourceFromEvent(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: (event: Event) => unknown;\n source?: {\n equal?: ValueEqualityFn<NoInfer<unknown> | undefined>;\n debugName?: string;\n };\n },\n): SourceFromEvent<unknown> {\n assertInInjectionContext(sourceFromEvent);\n const eventSignalSource = signalSource<unknown>(options?.source);\n\n const listener = (event: Event) => {\n if (options?.computedValue) {\n const computed = options.computedValue(event);\n eventSignalSource.set(computed);\n return;\n }\n eventSignalSource.set(event);\n };\n\n target.addEventListener(eventName, listener, options?.event);\n\n const destroyRef = inject(DestroyRef);\n\n const dispose = () => {\n target.removeEventListener(eventName, listener, options?.event);\n };\n\n destroyRef.onDestroy(() => {\n dispose();\n });\n\n return Object.assign(eventSignalSource, {\n dispose,\n });\n}\n","import { linkedSignal, Signal, signal } from '@angular/core';\n\nexport type StackSource<T> = Signal<T[] | undefined> & {\n set: (value: T) => void;\n};\n\n// ! this algo only works with object\nexport function stackedSource<T>(): StackSource<T> {\n const stack: unknown[] = [];\n const s2 = signal<T | undefined>(undefined);\n\n const l = linkedSignal({\n source: s2,\n computation: (current, previousData) => {\n if (!previousData) {\n stack.length = 0;\n return undefined;\n }\n\n const result = [...stack];\n stack.length = 0;\n return result;\n },\n });\n\n const set = (value: T) => {\n console.log('custom set', value);\n stack.push(value);\n console.log('stack', stack);\n\n s2.set(value);\n return;\n };\n\n return Object.assign(l, {\n set,\n }) as StackSource<T>;\n}\n","import { isSignal, Signal, signal, WritableSignal } from '@angular/core';\nimport {\n InsertionsStateFactory,\n InsertionStateFactoryContext,\n} from './query.core';\nimport { MergeObject } from './util/types/util.type';\nimport { FilterSource, IsEmptyObject } from './util/util.type';\n\nexport type StateOutput<StateType, Insertions> = MergeObject<\n Signal<StateType>,\n IsEmptyObject<Insertions> extends true ? {} : FilterSource<Insertions>\n>;\n\ntype StateConfig<State> = State | WritableSignal<State>;\n\n/**\n * Creates a signal state with optional insertions for adding methods and computed properties.\n *\n * The `state` function allows you to create a Signal-based state that can be extended with custom\n * methods and properties through insertions. Each insertion receives a context object with\n * `state`, `set`, `update` methods and previous insertions.\n *\n * @param stateConfig - The initial state value or a WritableSignal (e.g., linkedSignal)\n * @param insertions - Optional insertion functions to extend the state with methods and properties\n * @returns A Signal representing the state, merged with all insertion properties and methods\n *\n * @example\n * // Simple state with a primitive value\n * const counter = state(0);\n * console.log(counter()); // 0\n *\n * @example\n * // State with a linkedSignal\n * const origin = signal(5);\n * const doubled = state(linkedSignal(() => origin() * 2));\n * console.log(doubled()); // 10\n *\n * @example\n * // State with insertions to add methods\n * const origin = signal(5);\n * const counter = state(\n * linkedSignal(() => origin() * 2),\n * ({ update, set }) => ({\n * increment: () => update((current) => current + 1),\n * reset: () => set(0),\n * })\n * );\n * console.log(counter()); // 10\n * counter.increment();\n * console.log(counter()); // 11\n * counter.reset();\n * console.log(counter()); // 0\n *\n * @example\n * // State with multiple insertions (methods and computed properties)\n * const origin = signal(5);\n * const counter = state(\n * linkedSignal(() => origin() * 2),\n * ({ update, set }) => ({\n * increment: () => update((current) => current + 1),\n * reset: () => set(0),\n * }),\n * ({ state }) => ({\n * isOdd: computed(() => state() % 2 === 1),\n * })\n * );\n * console.log(counter()); // 10\n * console.log(counter.isOdd()); // false\n * counter.increment();\n * console.log(counter()); // 11\n * console.log(counter.isOdd()); // true\n *\n * @example\n * // State with source binding (methods bound to sources are not exposed)\n * const sourceSignal = source<number>();\n * const myState = state(0, ({ set }) => ({\n * setValue: afterRecomputation(sourceSignal, (value) => set(value)),\n * reset: () => set(0),\n * }));\n * console.log(myState()); // 0\n * // Note: setValue is not exposed on myState, only used internally\n * sourceSignal.set(34);\n * console.log(myState()); // 34\n * myState.reset();\n * console.log(myState()); // 0\n */\nexport function state<StateType>(\n stateConfig: StateConfig<StateType>\n): StateOutput<StateType, {}>;\nexport function state<StateType, Insertion1>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>\n): StateOutput<StateType, Insertion1>;\nexport function state<StateType, Insertion1, Insertion2>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<NoInfer<StateType>, Insertion2, Insertion1>\n): StateOutput<StateType, Insertion1 & Insertion2>;\nexport function state<StateType, Insertion1, Insertion2, Insertion3>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >\n): StateOutput<StateType, Insertion1 & Insertion2 & Insertion3>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >\n): StateOutput<StateType, Insertion1 & Insertion2 & Insertion3 & Insertion4>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >\n): StateOutput<\n StateType,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >\n): StateOutput<\n StateType,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >\n): StateOutput<\n StateType,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\nexport function state<StateType>(\n stateConfig: StateConfig<StateType>,\n ...insertions: any[]\n): StateOutput<StateType, {}> {\n const isSignalState = isSignal(stateConfig);\n const stateSignal = isSignalState\n ? (stateConfig as WritableSignal<StateType>)\n : signal(stateConfig as StateType);\n\n return Object.assign(\n stateSignal,\n (insertions as InsertionsStateFactory<StateType, {}>[])?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n state: stateSignal.asReadonly(),\n set: (newState: StateType) => stateSignal.set(newState),\n update: (updateFn: (currentState: StateType) => StateType) =>\n stateSignal.update(updateFn),\n insertions: acc as {},\n } as InsertionStateFactoryContext<StateType, {}>),\n };\n },\n {} as Record<string, unknown>\n )\n ) as unknown as StateOutput<StateType, {}>;\n}\n","import {\n linkedSignal,\n Signal,\n untracked,\n ValueEqualityFn,\n WritableSignal,\n} from '@angular/core';\nimport { IsUnknown } from './util/util.type';\nimport { ReadonlySource } from './util/source.type';\nimport { SourceBranded } from './util/util';\n\n/**\n * Converts an Angular signal into a readonly source with lazy emission semantics.\n *\n * This function bridges the gap between signals and sources by:\n * - Converting continuous signal values into discrete source emissions\n * - Implementing lazy emission (only emits on signal changes, not on first read)\n * - Supporting optional value transformation via computed function\n * - Providing both standard and value-preserving listener variants\n * - Enabling signal-to-source conversions for event-driven architectures\n *\n * @remarks\n * **Signal vs Source Semantics:**\n * - **Signals**: Continuously readable, always have a value, recompute on access\n * - **Sources**: Emit only on explicit changes, lazy by default (undefined on first read)\n * - toSource converts continuous signal behavior to discrete source emissions\n *\n * **Emission Behavior:**\n * - First read returns `undefined` by default (maintains source lazy semantics)\n * - Subsequent reads return new values only when the origin signal changes\n * - Use `preserveLastValue` variant to get immediate value on first read\n *\n * **Use Cases:**\n * - **Event-driven patterns**: Convert signals to sources for reactive chains\n * - **Debounced signals**: Wrap debounced signals as sources for queries/mutations\n * - **External state**: Convert RxJS signals (toSignal) to sources\n * - **Form signals**: Convert form control signals to sources for automatic submission\n * - **Route params**: Convert router param signals to sources for automatic queries\n * - **Filtering**: Transform signal values while converting to source\n *\n * **Transformation:**\n * - Without `computed`: Passes signal values through unchanged\n * - With `computed`: Applies transformation before emitting to source\n * - Useful for extracting fields, formatting, or type narrowing\n *\n * **Comparison with computedSource:**\n * - `toSource`: Converts signals to sources (signal → source)\n * - `computedSource`: Transforms sources to sources (source → source)\n * - Use toSource when bridging from signal world to source world\n *\n * @template SourceState - The type of values from the origin signal\n * @template ComputedValue - The type of values after optional computation\n *\n * @param signalOrigin - The signal or writable signal to convert.\n * Changes to this signal trigger source emissions.\n *\n * @param options - Optional configuration:\n * - `computed`: Function to transform signal values before emission\n * - `equal`: Custom equality function for change detection\n * - `debugName`: Name for debugging purposes\n *\n * @returns A readonly source that emits when the signal changes with:\n * - Standard behavior: First read returns `undefined`, subsequent reads return values after signal changes\n * - `preserveLastValue` property: Returns current value immediately on first read\n *\n * @example\n * Basic signal to source conversion\n * ```ts\n * const countSignal = signal(0);\n * const countSource = toSource(countSignal);\n *\n * // Use in query for automatic execution\n * const fetchData = query({\n * method: afterRecomputation(countSource, (count) => count),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/data/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Query executes when signal changes\n * countSignal.set(1);\n * // -> countSource emits 1\n * // -> fetchData executes with params 1\n *\n * countSignal.set(2);\n * // -> countSource emits 2\n * // -> fetchData executes with params 2\n * ```\n *\n * @example\n * Converting route params to source\n * ```ts\n * @Component({\n * selector: 'app-user-detail',\n * template: `...`,\n * })\n * export class UserDetailComponent {\n * route = inject(ActivatedRoute);\n *\n * // Convert route param to signal\n * userIdSignal = toSignal(\n * this.route.params.pipe(map(p => p['userId']))\n * );\n *\n * // Convert signal to source\n * userIdSource = toSource(this.userIdSignal);\n *\n * // Use source in query\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('user', () =>\n * query({\n * method: afterRecomputation(this.userIdSource, (id) => id),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n *\n * // Query automatically updates when route changes\n * }\n * ```\n *\n * @example\n * Transforming signal values during conversion\n * ```ts\n * type FormData = {\n * name: string;\n * email: string;\n * preferences: { newsletter: boolean };\n * };\n *\n * const formSignal = signal<FormData>({\n * name: '',\n * email: '',\n * preferences: { newsletter: false },\n * });\n *\n * // Extract only email for validation\n * const emailSource = toSource(formSignal, {\n * computed: (form) => form.email,\n * });\n *\n * // Use in async method\n * const validateEmail = asyncProcess({\n * method: afterRecomputation(emailSource, (email) => email),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * const response = await fetch('/api/validate-email', {\n * method: 'POST',\n * body: JSON.stringify({ email: params }),\n * });\n * return response.json();\n * },\n * });\n *\n * // Email validation triggers when form email changes\n * formSignal.update(form => ({ ...form, email: 'john@example.com' }));\n * // -> emailSource emits 'john@example.com'\n * // -> validateEmail executes\n * ```\n *\n * @example\n * Debounced signal to source\n * ```ts\n * const searchInputSignal = signal('');\n *\n * // Create debounced signal (using custom debounce logic)\n * const debouncedSearchSignal = computed(() => {\n * const input = searchInputSignal();\n * // Debounce logic would go here\n * return input;\n * });\n *\n * // Convert to source\n * const debouncedSearchSource = toSource(debouncedSearchSignal);\n *\n * // Use in query\n * const searchResults = query({\n * method: afterRecomputation(debouncedSearchSource, (term) => term),\n * loader: async ({ params }) => {\n * if (!params) return [];\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * });\n *\n * // Query executes only after debounce\n * searchInputSignal.set('ang');\n * searchInputSignal.set('angu');\n * searchInputSignal.set('angular');\n * // -> Eventually debouncedSearchSource emits 'angular'\n * // -> searchResults query executes once\n * ```\n *\n * @example\n * Form control signal to source\n * ```ts\n * @Component({\n * selector: 'app-search',\n * template: `\n * <input [formControl]=\"searchControl\" />\n * `,\n * })\n * export class SearchComponent {\n * searchControl = new FormControl('');\n *\n * // Convert form control value to signal\n * searchSignal = toSignal(\n * this.searchControl.valueChanges.pipe(\n * debounceTime(300),\n * distinctUntilChanged()\n * ),\n * { initialValue: '' }\n * );\n *\n * // Convert signal to source\n * searchSource = toSource(this.searchSignal);\n *\n * // Use in store\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('results', () =>\n * query({\n * method: afterRecomputation(this.searchSource, (term) => term),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n * }\n * ```\n *\n * @example\n * Custom equality for change detection\n * ```ts\n * type SearchParams = { query: string; timestamp: number };\n *\n * const paramsSignal = signal<SearchParams>({\n * query: '',\n * timestamp: Date.now(),\n * });\n *\n * // Only emit when query changes, ignore timestamp\n * const querySource = toSource(paramsSignal, {\n * computed: (params) => params.query,\n * equal: (a, b) => a === b, // Compare strings only\n * });\n *\n * // Update with same query but different timestamp\n * paramsSignal.set({ query: 'test', timestamp: Date.now() });\n * // -> querySource emits 'test'\n *\n * paramsSignal.set({ query: 'test', timestamp: Date.now() });\n * // -> querySource does NOT emit (same query)\n *\n * paramsSignal.set({ query: 'new', timestamp: Date.now() });\n * // -> querySource emits 'new'\n * ```\n *\n * @example\n * Using preserveLastValue for immediate access\n * ```ts\n * const countSignal = signal(5);\n * const countSource = toSource(countSignal);\n *\n * // Standard behavior - first read is undefined\n * console.log(countSource()); // undefined\n *\n * countSignal.set(10);\n * console.log(countSource()); // 10\n *\n * // Using preserveLastValue - gets current value immediately\n * const immediateCount = countSource.preserveLastValue;\n * console.log(immediateCount()); // 10\n *\n * countSignal.set(15);\n * console.log(immediateCount()); // 15\n * ```\n *\n * @example\n * Complex transformation with validation\n * ```ts\n * type RawInput = { text: string; valid?: boolean };\n *\n * const inputSignal = signal<RawInput>({ text: '' });\n *\n * // Transform and validate during conversion\n * const validInputSource = toSource(inputSignal, {\n * computed: (input) => {\n * const trimmed = input.text.trim();\n * if (trimmed.length < 3) {\n * return null; // Invalid input\n * }\n * return {\n * text: trimmed.toLowerCase(),\n * length: trimmed.length,\n * };\n * },\n * });\n *\n * // Use in mutation\n * const submitInput = mutation({\n * method: afterRecomputation(validInputSource, (data) => data),\n * loader: async ({ params }) => {\n * if (!params) {\n * throw new Error('Invalid input');\n * }\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * // Invalid input\n * inputSignal.set({ text: 'ab' });\n * // -> validInputSource emits null\n * // -> submitInput throws error\n *\n * // Valid input\n * inputSignal.set({ text: 'Valid Input' });\n * // -> validInputSource emits { text: 'valid input', length: 11 }\n * // -> submitInput executes with transformed data\n * ```\n */\nexport function toSource<SourceState, ComputedValue>(\n signalOrigin: Signal<SourceState> | WritableSignal<SourceState>,\n options?: {\n computed?: (sourceValue: NoInfer<SourceState>) => ComputedValue;\n equal?: ValueEqualityFn<NoInfer<SourceState> | undefined>;\n debugName?: string;\n },\n): ReadonlySource<\n IsUnknown<ComputedValue> extends true ? SourceState : ComputedValue\n> {\n const sourceState = linkedSignal<SourceState | undefined>(signalOrigin, {\n ...(options?.equal && { equal: options?.equal }), // add the equal function here, it may helps to detect changes when using scalar values\n ...(options?.debugName && {\n debugName: options?.debugName + '_sourceState',\n }),\n });\n\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<SourceState, any>({\n source: sourceState as Signal<SourceState>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n //! use untracked to avoid computation to be re-evaluated when used inside another effect/computed\n return untracked(() =>\n options?.computed\n ? options?.computed?.(currentSourceState)\n : currentSourceState,\n );\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n },\n SourceBranded,\n ) as ReadonlySource<any>;\n}\n","import { EventEmitter, Type } from '@angular/core';\nimport { StoreConfigConstraints } from '../craft';\nimport { SignalSource } from '../signal-source';\nimport { ExtractSignalPropsAndMethods } from './extract-signal-props-and-methods';\nimport { ReadonlySource } from './source.type';\nimport { SourceBranded } from './util';\n\nexport type FilterPrivateFields<T> = {\n [K in keyof T as K extends `_${string}` ? never : K]: T[K];\n};\n\nexport type ToConnectableSourceFromInject<Sources> = {\n [K in keyof Sources]: Sources[K] extends SignalSource<infer SourceType>\n ? ReadonlySource<SourceType>\n : never;\n};\n\nexport type ToConnectableMethodFromInject<Methods> = RemoveIndexSignature<{\n [K in keyof Methods]?: Methods[K] extends (payload: infer Payload) => any\n ? IsUnknown<Payload> extends true\n ?\n | ReadonlySource<any>\n | {\n subscribe: EventEmitter<any>['subscribe'];\n }\n :\n | ReadonlySource<Payload>\n | {\n subscribe: EventEmitter<Payload>['subscribe'];\n }\n : never;\n}>;\n\nexport type IsUnknown<T> = unknown extends T\n ? [T] extends [unknown]\n ? true\n : false\n : false;\n\nexport type RemoveIndexSignature<T> = {\n [K in keyof T as string extends K\n ? never\n : number extends K\n ? never\n : symbol extends K\n ? never\n : K]: T[K];\n};\n\nexport type IsEmptyObject<T> = keyof T extends never ? true : false;\n\nexport type ExcludeCommonKeys<Origin, Target> = {\n [key in keyof Origin as key extends keyof Target ? never : key]: Origin[key];\n};\n\nexport const STORE_CONFIG_TOKEN = {\n NAME: '_STORE_NAME_',\n PROVIDED_IN: '_STORE_PROVIDED_IN_',\n} as const;\nexport type StoreConfigToken = typeof STORE_CONFIG_TOKEN;\n\nexport type ReplaceStoreConfigToken<\n StandaloneOutputName extends string,\n StoreConfig extends StoreConfigConstraints,\n> = StandaloneOutputName extends `${infer StoreNamePrefix}${typeof STORE_CONFIG_TOKEN.NAME}${infer StoreNameSuffix}`\n ? ReplaceStoreConfigToken<\n `${StoreNamePrefix}${Capitalize<StoreConfig['name']>}${StoreNameSuffix}`,\n StoreConfig\n >\n : StandaloneOutputName extends `${infer StoreProvidedInPrefix}${typeof STORE_CONFIG_TOKEN.PROVIDED_IN}${infer StoreProvidedInSuffix}`\n ? ReplaceStoreConfigToken<\n `${StoreProvidedInPrefix}${Capitalize<\n StoreConfig['providedIn']\n >}${StoreProvidedInSuffix}`,\n StoreConfig\n >\n : StandaloneOutputName;\n\nexport type FilterMethodsBoundToSources<\n Methods extends {},\n Rest,\n MethodPrefix extends string,\n MethodName extends string,\n Acc = {},\n> = Rest extends [infer First, ...infer Next]\n ? First extends keyof Methods\n ? Methods[First] extends {\n [Key in MethodName]: infer Method;\n }\n ? [Method] extends [ReadonlySource<infer SourceState>]\n ? FilterMethodsBoundToSources<\n Methods,\n Next,\n MethodPrefix,\n MethodName,\n Acc\n >\n : FilterMethodsBoundToSources<\n Methods,\n Next,\n MethodPrefix,\n MethodName,\n Acc & {\n [K in First as `${MethodPrefix}${Capitalize<string & K>}`]: [\n Method,\n ] extends [Function]\n ? Method\n : never;\n }\n >\n : FilterMethodsBoundToSources<\n Methods,\n Next,\n MethodPrefix,\n MethodName,\n Acc\n >\n : FilterMethodsBoundToSources<Methods, Next, MethodPrefix, MethodName, Acc>\n : Acc;\n\nexport type FilterSource<Insertions> = {\n [K in keyof Insertions as Insertions[K] extends SourceBranded\n ? never\n : K]: Insertions[K];\n};\n\n// Helper type to defer evaluation and avoid infinite recursion\nexport type DeferredExtract<Insertions> =\n UnionToTuple<keyof Insertions> extends infer Keys\n ? ExtractSignalPropsAndMethods<\n Insertions,\n Keys,\n { props: {}; methods: Record<string, Function> }\n >\n : never;\n\nexport type HasKeys<T> = T extends object\n ? keyof T extends never\n ? false\n : true\n : false;\ntype _FlatRecord<T> = T[keyof T] extends infer U\n ? { [K in keyof U]: U[K] }\n : never;\n\nexport type FlatRecord<T> = Prettify<UnionToIntersection<_FlatRecord<T>>>;\n\n// It is not possible to get all the properties key of an optional object, so make the optional properties required\nexport type MakeOptionalPropertiesRequired<\n T,\n K extends keyof T = keyof T,\n> = T & {\n [P in K]-?: T[P];\n};\n\nexport type MergeObject<A, B> = A & B;\n\nexport type MergeObjects<F extends unknown[], Acc = {}> = F extends [\n infer First,\n ...infer Rest,\n]\n ? First extends object\n ? MergeObjects<Rest, MergeObject<Acc, First>>\n : Prettify<Acc>\n : Prettify<Acc>;\n\n// from https://github.com/ecyrbe/zodios/blob/main/src/utils.types.ts\n/**\n * trick to combine multiple unions of objects into a single object\n * only works with objects not primitives\n * @param union - Union of objects\n * @returns Intersection of objects\n */\nexport type UnionToIntersection<union> = (\n union extends any ? (k: union) => void : never\n) extends (k: infer intersection) => void\n ? intersection\n : never;\n\n/**\n * get last element of union\n * @param Union - Union of any types\n * @returns Last element of union\n */\ntype GetUnionLast<Union> =\n UnionToIntersection<\n Union extends any ? () => Union : never\n > extends () => infer Last\n ? Last\n : never;\n\n/**\n * Convert union to tuple\n * @param Union - Union of any types, can be union of complex, composed or primitive types\n * @returns Tuple of each elements in the union\n */\nexport type UnionToTuple<Union, Tuple extends unknown[] = []> = [\n Union,\n] extends [never]\n ? Tuple\n : UnionToTuple<\n Exclude<Union, GetUnionLast<Union>>,\n [GetUnionLast<Union>, ...Tuple]\n >;\n\nexport type HasChild<T> = T extends any[]\n ? false\n : T extends object\n ? true\n : false;\n\nexport type OmitStrict<T, K extends keyof T> = T extends any\n ? Pick<T, Exclude<keyof T, K>>\n : never;\n\n/**\n * Negates a boolean type.\n */\nexport type Not<T extends boolean> = T extends true ? false : true;\n\n/**\n * @internal\n */\nconst secret = Symbol('secret');\n\n/**\n * @internal\n */\ntype Secret = typeof secret;\n\n/**\n * Checks if the given type is `never`.\n */\nexport type IsNever<T> = [T] extends [never] ? true : false;\n\nexport type IsAny<T> = [T] extends [Secret] ? Not<IsNever<T>> : false;\n\nexport type InferInjectedType<T extends Type<unknown>> =\n T extends Type<infer U> ? U : never;\n\nexport type Prettify<T> = {\n [K in keyof T]: T[K];\n} & {};\n","// todo handle update of array of objects\nexport function createNestedStateUpdate({\n state,\n keysPath,\n value,\n}: {\n state: any;\n keysPath: string[];\n value: any;\n}): any {\n if (keysPath.length === 0) {\n return value;\n }\n\n const [currentKey, ...remainingKeys] = keysPath;\n const currentState = state[currentKey] || {};\n\n return {\n ...state,\n [currentKey]:\n remainingKeys.length === 0\n ? Array.isArray(currentState)\n ? value\n : typeof value === 'object' && value !== null && !Array.isArray(value)\n ? { ...currentState, ...value }\n : value\n : createNestedStateUpdate({\n state: currentState,\n keysPath: remainingKeys,\n value,\n }),\n };\n}\nexport function getNestedStateValue({\n state,\n keysPath,\n}: {\n state: any;\n keysPath: string[];\n}): any {\n return keysPath.reduce((currentState, key) => {\n if (currentState && typeof currentState === 'object') {\n return currentState[key];\n }\n return undefined;\n }, state);\n}\n","import { ResourceStatus, Signal, WritableSignal } from '@angular/core';\nimport {\n CustomReloadOnSpecificMutationStatus,\n FilterQueryById,\n PatchQueryFn,\n PatchMutationQuery,\n QueryAndMutationRecordConstraints,\n ReloadQueriesConfig,\n} from './util/types/shared.type';\nimport { ResourceByIdRef } from './resource-by-id';\nimport {\n getNestedStateValue,\n createNestedStateUpdate,\n} from './util/update-state.util';\nimport { MergeObjects } from './util//types/util.type';\nimport {\n ResourceByIdLikeMutationRef,\n ResourceLikeMutationRef,\n} from './mutation';\nimport { CraftResourceRef } from './util/craft-resource-ref';\nimport { QueryParamsToState } from './query-param';\nimport { Prettify } from './util/util.type';\n\nexport interface QueryParamNavigationOptions {\n queryParamsHandling?: 'merge' | 'preserve' | '';\n onSameUrlNavigation?: 'reload' | 'ignore';\n replaceUrl?: boolean;\n skipLocationChange?: boolean;\n}\n\nexport type MutationResourceRefHelper<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = ResourceLikeMutationRef<\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params'],\n QueryAndMutationRecord['mutation']['isMethod'],\n QueryAndMutationRecord['mutation']['args'],\n QueryAndMutationRecord['mutation']['sourceParams'],\n QueryAndMutationRecord['mutation']['insertions']\n>;\n\nexport type MutationResourceByIdRefHelper<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = ResourceByIdLikeMutationRef<\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params'],\n QueryAndMutationRecord['mutation']['isMethod'],\n QueryAndMutationRecord['mutation']['args'],\n QueryAndMutationRecord['mutation']['sourceParams'],\n QueryAndMutationRecord['mutation']['insertions'],\n QueryAndMutationRecord['mutation']['groupIdentifier']\n>;\n\ntype UpdateData<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = MergeObjects<\n [\n {\n queryResource: CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationResource: CraftResourceRef<\n NoInfer<QueryAndMutationRecord['mutation']['state']>,\n NoInfer<QueryAndMutationRecord['mutation']['params']>\n >;\n mutationParams: NonNullable<\n NoInfer<QueryAndMutationRecord['mutation']['params']>\n >;\n },\n QueryAndMutationRecord['query']['isGroupedResource'] extends true\n ? {\n queryIdentifier: QueryAndMutationRecord['query']['groupIdentifier'];\n queryResources: ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n }\n : {},\n QueryAndMutationRecord['mutation']['groupIdentifier'] extends\n | string\n | number\n ? {\n mutationIdentifier: QueryAndMutationRecord['mutation']['groupIdentifier'];\n mutationResources: ResourceByIdRef<\n string,\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params']\n >;\n }\n : {},\n ]\n>;\n\nexport type QueryDeclarativeEffect<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = MergeObjects<\n [\n {\n /**\n * Run when the mutation is in loading state.\n */\n optimisticUpdate?: (\n data: UpdateData<QueryAndMutationRecord> & {\n testData: QueryAndMutationRecord['query']['groupIdentifier'];\n },\n ) => QueryAndMutationRecord['query']['state'];\n /**\n * Run when the mutation is in loaded state.\n */\n update?: (\n data: UpdateData<QueryAndMutationRecord>,\n ) => QueryAndMutationRecord['query']['state'];\n reload?: ReloadQueriesConfig<QueryAndMutationRecord>;\n /**\n * Run when the mutation is in loading state.\n * Will patch the query specific state with the mutation data.\n * If the query is loading, it will not patch.\n * If the mutation data is not compatible with the query state, it will not patch.\n * Be careful! If the mutation is already in a loading state, trigger the mutation again will cancelled the previous mutation loader and will patch with the new value.\n */\n optimisticPatch?: PatchMutationQuery<QueryAndMutationRecord>;\n /**\n * Run when the mutation is in loaded state.\n * Will patch the query specific state with the mutation data.\n * If the query is loading, it will not patch.\n * If the mutation data is not compatible with the query state, it will not patch.\n * Be careful! If the mutation is already in a loading state, trigger the mutation again will cancelled the previous mutation loader and will patch with the new value.\n */\n patch?: PatchMutationQuery<QueryAndMutationRecord>;\n },\n QueryAndMutationRecord['mutation']['isGroupedResource'] extends true\n ? {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n : QueryAndMutationRecord['query']['isGroupedResource'] extends true\n ? {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n : {},\n ]\n>;\n\nexport function triggerQueryReloadFromMutationChange<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n reload,\n mutationStatus,\n queryResource,\n mutationResource,\n mutationParamsSrc,\n queryIdentifier,\n queryResources,\n mutationIdentifier,\n mutationResources,\n}: {\n reload: ReloadQueriesConfig<QueryAndMutationRecord>;\n mutationStatus: string;\n queryResource: CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n queryResources:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | undefined;\n mutationResource: CraftResourceRef<any, any>;\n mutationParamsSrc: Signal<\n QueryAndMutationRecord['mutation']['params'] | undefined\n >;\n queryIdentifier: QueryAndMutationRecord['query']['groupIdentifier'];\n mutationIdentifier: QueryAndMutationRecord['mutation']['groupIdentifier'];\n mutationResources: ResourceByIdRef<string, any, unknown> | undefined;\n}) {\n const statusMappings = {\n onMutationError: 'error',\n onMutationResolved: 'resolved',\n onMutationLoading: 'loading',\n };\n\n Object.entries(reload).forEach(([reloadType, reloadConfig]) => {\n const expectedStatus =\n statusMappings[reloadType as keyof typeof statusMappings];\n\n if (expectedStatus && mutationStatus === expectedStatus) {\n if (typeof reloadConfig === 'function') {\n if (\n reloadConfig({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n mutationIdentifier,\n mutationResources,\n queryResources,\n })\n ) {\n queryResource.reload();\n }\n } else if (reloadConfig) {\n queryResource.reload();\n }\n }\n });\n}\n\nexport function triggerQueryReloadOnMutationStatusChange<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n mutationStatus,\n queryResourceTarget,\n mutationEffectOptions,\n mutationResource,\n mutationParamsSrc,\n reloadCConfig,\n mutationIdentifier,\n mutationResources,\n}: {\n mutationStatus: string;\n queryResourceTarget:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationEffectOptions: QueryDeclarativeEffect<QueryAndMutationRecord>;\n mutationResource: CraftResourceRef<any, any>;\n mutationParamsSrc: Signal<QueryAndMutationRecord['mutation']['params']>;\n reloadCConfig: {\n onMutationError?:\n | boolean\n | CustomReloadOnSpecificMutationStatus<QueryAndMutationRecord>;\n onMutationResolved?:\n | boolean\n | CustomReloadOnSpecificMutationStatus<QueryAndMutationRecord>;\n onMutationLoading?:\n | boolean\n | CustomReloadOnSpecificMutationStatus<QueryAndMutationRecord>;\n };\n mutationIdentifier:\n | QueryAndMutationRecord['mutation']['groupIdentifier']\n | undefined;\n mutationResources:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params']\n >\n | undefined;\n}) {\n if (\n (['error', 'loading', 'resolved'] satisfies ResourceStatus[]).includes(\n mutationStatus as any,\n )\n ) {\n if ('hasValue' in queryResourceTarget) {\n const queryResource = queryResourceTarget;\n triggerQueryReloadFromMutationChange({\n reload: reloadCConfig,\n mutationStatus,\n queryResource,\n mutationResource,\n mutationParamsSrc,\n queryIdentifier: undefined,\n mutationIdentifier,\n mutationResources,\n queryResources: undefined,\n });\n return;\n }\n const queryResourcesById = queryResourceTarget as ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n Object.entries(\n queryResourcesById() as Record<string, CraftResourceRef<any, any>>,\n )\n .filter(([queryIdentifier, queryResource]) => {\n return (\n mutationEffectOptions as {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n ).filter({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourceTarget,\n mutationIdentifier,\n mutationResources,\n } as any);\n })\n .forEach(([queryIdentifier, queryResource]) => {\n triggerQueryReloadFromMutationChange({\n reload: reloadCConfig,\n mutationStatus,\n queryResource,\n mutationResource,\n mutationParamsSrc,\n queryIdentifier,\n mutationIdentifier,\n mutationResources,\n queryResources: queryResourceTarget,\n });\n });\n }\n}\n\nexport function setAllPatchFromMutationOnQueryValue<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n mutationStatus,\n queryResourceTarget,\n mutationEffectOptions,\n mutationResource,\n mutationParamsSrc,\n mutationIdentifier,\n mutationResources,\n}: {\n mutationStatus: string;\n queryResourceTarget:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationEffectOptions: QueryDeclarativeEffect<QueryAndMutationRecord>;\n mutationResource: CraftResourceRef<any, any>;\n mutationParamsSrc: Signal<QueryAndMutationRecord['mutation']['params']>;\n mutationIdentifier:\n | QueryAndMutationRecord['mutation']['groupIdentifier']\n | undefined;\n mutationResources:\n | MutationResourceByIdRefHelper<QueryAndMutationRecord>\n | undefined;\n}) {\n if (mutationStatus !== 'loading' && mutationStatus !== 'resolved') {\n return;\n }\n const patchTarget =\n mutationStatus === 'loading'\n ? mutationEffectOptions.optimisticPatch\n : mutationEffectOptions.patch;\n if (!patchTarget) {\n return;\n }\n if ('hasValue' in queryResourceTarget) {\n const queryResource = queryResourceTarget;\n Object.entries(\n patchTarget as Record<string, PatchQueryFn<any, any>>,\n ).forEach(([path, optimisticPatch]) => {\n const queryValue = queryResource.hasValue()\n ? queryResource.value()\n : undefined;\n const optimisticValue = optimisticPatch({\n mutationResource,\n queryResource,\n queryResources: undefined,\n queryIdentifier: undefined,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n targetedState: getNestedStateValue({\n state: queryValue,\n keysPath: path.split('.'),\n }),\n mutationIdentifier,\n mutationResources,\n });\n const updatedValue = createNestedStateUpdate({\n state: queryValue,\n keysPath: path.split('.'),\n value: optimisticValue,\n });\n queryResource.set(updatedValue);\n });\n return;\n }\n const queryResourcesById = queryResourceTarget as ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n Object.entries(\n queryResourcesById() as Record<string, CraftResourceRef<any, any>>,\n )\n .filter(([queryIdentifier, queryResource]) =>\n (\n mutationEffectOptions as {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n ).filter({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourcesById,\n mutationIdentifier,\n mutationResources,\n } as any),\n )\n .forEach(([queryIdentifier, queryResource]) => {\n Object.entries(\n patchTarget as Record<string, PatchQueryFn<any, any>>,\n ).forEach(([path, patch]) => {\n const queryValue = queryResource.hasValue()\n ? queryResource.value()\n : undefined;\n const optimisticValue = patch({\n mutationResource,\n queryResource,\n queryResources: queryResourcesById,\n queryIdentifier,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n targetedState: getNestedStateValue({\n state: queryValue,\n keysPath: path.split('.'),\n }),\n mutationIdentifier,\n mutationResources,\n });\n const updatedValue = createNestedStateUpdate({\n state: queryValue,\n keysPath: path.split('.'),\n value: optimisticValue,\n });\n queryResource.set(updatedValue);\n });\n });\n}\n\nexport function setAllUpdatesFromMutationOnQueryValue<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n mutationStatus,\n queryResourceTarget,\n mutationEffectOptions,\n mutationResource,\n mutationParamsSrc,\n mutationIdentifier,\n mutationResources,\n}: {\n mutationStatus: string;\n queryResourceTarget:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationEffectOptions: QueryDeclarativeEffect<QueryAndMutationRecord>;\n mutationResource: CraftResourceRef<any, any> | undefined;\n mutationParamsSrc: Signal<QueryAndMutationRecord['mutation']['params']>;\n mutationIdentifier:\n | QueryAndMutationRecord['mutation']['groupIdentifier']\n | undefined;\n mutationResources:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params']\n >\n | undefined;\n}) {\n if (mutationStatus !== 'loading' && mutationStatus !== 'resolved') {\n return;\n }\n const updateTarget =\n mutationStatus === 'loading'\n ? mutationEffectOptions.optimisticUpdate\n : mutationEffectOptions.update;\n if (!updateTarget) {\n return;\n }\n\n if ('hasValue' in queryResourceTarget) {\n const queryResource = queryResourceTarget;\n const updatedValue = updateTarget({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier: undefined,\n queryResources: undefined,\n mutationIdentifier,\n mutationResources,\n } as any);\n queryResource.set(updatedValue);\n return;\n }\n const queryResourceById = queryResourceTarget as ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n Object.entries(\n queryResourceById() as Record<string, CraftResourceRef<any, any>>,\n )\n .filter(([queryIdentifier, queryResource]) =>\n (\n mutationEffectOptions as {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n ).filter({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourceTarget,\n mutationIdentifier,\n mutationResources,\n } as any),\n )\n .forEach(([queryIdentifier, queryResource]) => {\n const updatedValue = updateTarget({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourceTarget,\n mutationIdentifier,\n mutationResources,\n } as any);\n queryResource.set(updatedValue);\n });\n}\n\nexport type InsertionParams<\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n> = {\n state: Signal<ResourceState>;\n set: (newState: ResourceState) => ResourceState;\n update: (\n updateFn: (currentState: ResourceState) => ResourceState,\n ) => ResourceState;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n resource: CraftResourceRef<ResourceState, ResourceParams>;\n resourceParamsSrc: WritableSignal<ResourceParams | undefined>;\n // 👇 Seems required for insertLocalStoragePersister, otherwise TS says they can be missing\n resourceById: never;\n identifier: never;\n};\n\nexport type InsertionsFactory<\n ResourceState extends object | undefined,\n ResourceParams,\n InsertsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionParams<\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >,\n) => InsertsOutputs;\n\nexport type InsertionByIdParams<\n GroupIdentifier extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n> = {\n state: Signal<ResourceState>;\n set: (newState: ResourceState) => ResourceState;\n update: (\n updateFn: (currentState: ResourceState) => ResourceState,\n ) => ResourceState;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n resourceById: ResourceByIdRef<GroupIdentifier, ResourceState, ResourceParams>;\n resource: never;\n resourceParamsSrc: WritableSignal<ResourceParams | undefined>;\n identifier: (params: NonNullable<ResourceParams>) => GroupIdentifier;\n};\n\nexport type InsertionStateFactoryContext<StateType, PreviousInsertionsOutputs> =\n {\n state: Signal<StateType>;\n set: (newState: StateType) => StateType;\n update: (updateFn: (currentState: StateType) => StateType) => StateType;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n };\n\nexport type QueryParamMethods<QueryParamsState> = {\n patch: (\n params: Partial<QueryParamsState>,\n options?: QueryParamNavigationOptions,\n ) => void;\n reset: (options?: QueryParamNavigationOptions) => void;\n set: (\n params: QueryParamsState,\n options?: QueryParamNavigationOptions,\n ) => QueryParamsState;\n update: (\n updateFn: (currentParams: QueryParamsState) => QueryParamsState,\n options?: QueryParamNavigationOptions,\n ) => QueryParamsState;\n};\n\nexport type InsertionQueryParamsFactoryContext<\n QueryParamsType,\n PreviousInsertionsOutputs,\n //! do not get the QueryParamState directly from the queryParam utility (it's broke the inference),\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n> = QueryParamMethods<QueryParamsState> & {\n state: Signal<QueryParamsState>;\n config: QueryParamsType;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n};\n\nexport type InsertionsByIdFactory<\n ResourceState extends object | undefined,\n ResourceParams,\n GroupIdentifier extends string,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionByIdParams<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >,\n) => InsertionsOutputs;\n\nexport type InsertionResourceFactoryContext<\n GroupIdentifier,\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n> = [unknown] extends [GroupIdentifier]\n ? InsertionParams<ResourceState, ResourceParams, PreviousInsertionsOutputs>\n : InsertionByIdParams<\n GroupIdentifier & string,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >;\nexport type InsertionsResourcesFactory<\n GroupIdentifier,\n ResourceState extends object | undefined,\n ResourceParams,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionResourceFactoryContext<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >,\n) => InsertionsOutputs;\n\nexport type InsertionsStateFactory<\n State,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionStateFactoryContext<State, PreviousInsertionsOutputs>,\n) => InsertionsOutputs;\n\nexport type InsertionsQueryParamsFactory<\n QueryParamsType,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionQueryParamsFactoryContext<\n QueryParamsType,\n PreviousInsertionsOutputs\n >,\n) => InsertionsOutputs;\n\nexport type DefaultInsertionByIdParams = InsertionByIdParams<\n string,\n {},\n unknown,\n {}\n>;\n\nexport type DefaultInsertionParams = InsertionParams<{}, unknown, unknown>;\n","import {\n ResourceRef,\n Injector,\n effect,\n untracked,\n linkedSignal,\n Signal,\n inject,\n computed,\n} from '@angular/core';\nimport {\n ResourceLikeMutationRef,\n ResourceByIdLikeMutationRef,\n} from '../mutation';\nimport {\n QueryDeclarativeEffect,\n setAllUpdatesFromMutationOnQueryValue,\n triggerQueryReloadOnMutationStatusChange,\n setAllPatchFromMutationOnQueryValue,\n} from '../query.core';\nimport { ResourceByIdRef } from '../resource-by-id';\nimport { explicitNestedEffect } from './types/util';\nimport { InternalType } from './types/util.type';\nimport { ResourceByIdLikeQueryRef, ResourceLikeQueryRef } from '../query';\nimport { CraftResourceRef } from './craft-resource-ref';\n\n// todo improve internal function types\nexport function reactOnMutationEffect<\n QueryResourceState,\n QueryResourceParams,\n QueryResourceArgsParams,\n QueryIsMethod extends boolean,\n QuerySourceParams,\n QueryGroupIdentifier,\n QueryInsertions,\n MutationResourceState,\n MutationResourceParams,\n MutationResourceArgsParams,\n MutationIsMethod,\n MutationSourceParams,\n MutationGroupIdentifier,\n MutationInsertions,\n>(\n {\n queryTargeted,\n mutationTargeted,\n }: {\n queryTargeted:\n | ResourceLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions\n >\n | ResourceByIdLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions,\n QueryGroupIdentifier\n >;\n mutationTargeted:\n | ResourceLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions\n >\n | ResourceByIdLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions,\n MutationGroupIdentifier\n >;\n },\n mutationEffectOptions: QueryDeclarativeEffect<{\n query: InternalType<\n NoInfer<QueryResourceState>,\n NoInfer<QueryResourceParams>,\n NoInfer<QueryResourceArgsParams>,\n [unknown] extends [NoInfer<QueryGroupIdentifier>] ? false : true,\n NoInfer<QueryIsMethod>,\n NoInfer<QueryInsertions>,\n NoInfer<QueryGroupIdentifier>,\n NoInfer<QuerySourceParams>\n >;\n mutation: InternalType<\n NoInfer<MutationResourceState>,\n NoInfer<MutationResourceParams>,\n NoInfer<MutationResourceArgsParams>,\n [unknown] extends [MutationGroupIdentifier] ? false : true,\n NoInfer<MutationIsMethod>,\n NoInfer<MutationInsertions>,\n NoInfer<MutationGroupIdentifier>,\n NoInfer<MutationSourceParams>\n >;\n }>,\n) {\n const _injector = inject(Injector);\n if (mutationTargeted.type === 'resourceLike') {\n const mutationResource = mutationTargeted;\n return effect(() => {\n const mutationStatus = mutationResource.status();\n const mutationParamsSrc = mutationTargeted.resourceParamsSrc;\n // use to track the value of the mutation\n const _mutationValueChanged = mutationResource.hasValue()\n ? mutationResource.value()\n : undefined;\n\n if (\n mutationEffectOptions?.optimisticUpdate ||\n mutationEffectOptions.update\n ) {\n untracked(() => {\n setAllUpdatesFromMutationOnQueryValue({\n mutationStatus,\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions,\n mutationResource: mutationResource as any,\n mutationParamsSrc,\n mutationIdentifier: undefined,\n mutationResources: undefined,\n } as any);\n });\n }\n const reloadCConfig = mutationEffectOptions.reload;\n if (reloadCConfig) {\n untracked(() => {\n triggerQueryReloadOnMutationStatusChange({\n mutationStatus,\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource: mutationResource as unknown as ResourceRef<any>,\n mutationParamsSrc,\n reloadCConfig,\n mutationIdentifier: undefined,\n mutationResources: undefined,\n } as any);\n });\n }\n if (\n mutationEffectOptions.optimisticPatch ||\n mutationEffectOptions.patch\n ) {\n untracked(() => {\n setAllPatchFromMutationOnQueryValue({\n mutationStatus,\n //@ts-expect-error not understand from where the error come from\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource: mutationResource as unknown as CraftResourceRef<\n any,\n any\n >,\n mutationParamsSrc,\n mutationIdentifier: undefined,\n mutationResources: undefined,\n });\n });\n }\n });\n }\n const mutationResources = mutationTargeted._resourceById;\n\n const newMutationResourceRefForNestedEffect = linkedSignal<\n ResourceByIdRef<\n MutationGroupIdentifier & string,\n MutationResourceState,\n MutationResourceParams\n >,\n { newKeys: QueryGroupIdentifier[] } | undefined\n >({\n //@ts-expect-error I do not understand why it is not satisfies\n source: mutationResources,\n computation: (currentSource, previous) => {\n if (!currentSource || !Object.keys(currentSource).length) {\n return undefined;\n }\n\n const currentKeys = Object.keys(currentSource) as QueryGroupIdentifier[];\n const previousKeys = Object.keys(\n previous?.source || {},\n ) as QueryGroupIdentifier[];\n\n // Find keys that exist in current but not in previous\n const newKeys = currentKeys.filter((key) => !previousKeys.includes(key));\n\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n }) as unknown as Signal<{ newKeys: MutationGroupIdentifier[] } | undefined>;\n\n return effect(() => {\n if (!newMutationResourceRefForNestedEffect()?.newKeys) {\n return;\n }\n newMutationResourceRefForNestedEffect()?.newKeys.forEach(\n (mutationIdentifier) => {\n const mutationResource =\n mutationResources()[\n mutationIdentifier as MutationGroupIdentifier & string\n ];\n if (!mutationResource) {\n return;\n }\n const safeMutationResourceValue = computed(() =>\n mutationResource.hasValue()\n ? mutationResource.value()\n : (undefined as unknown as MutationResourceState),\n );\n explicitNestedEffect(\n _injector,\n [\n mutationResource.status,\n safeMutationResourceValue,\n mutationResource.paramSrc,\n ],\n ([mutationStatus, _value]) => {\n const mutationParamsSrc = mutationResource.paramSrc;\n if (\n typeof mutationParamsSrc === 'function' &&\n mutationParamsSrc()\n ) {\n // ! keep this check, it is used to track mutationParamsSrc, otherwise it does not works\n }\n if (\n mutationEffectOptions?.optimisticUpdate ||\n mutationEffectOptions.update\n ) {\n untracked(() => {\n setAllUpdatesFromMutationOnQueryValue({\n mutationStatus,\n queryResourceTarget: queryTargeted as any,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource,\n mutationParamsSrc,\n mutationIdentifier,\n mutationResources:\n mutationResources as unknown as ResourceByIdRef<\n string,\n any,\n any\n >,\n });\n });\n }\n const reloadCConfig = mutationEffectOptions.reload;\n if (reloadCConfig) {\n untracked(() => {\n triggerQueryReloadOnMutationStatusChange({\n mutationStatus,\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource,\n mutationParamsSrc,\n reloadCConfig,\n mutationIdentifier,\n mutationResources:\n mutationResources as unknown as ResourceByIdRef<\n string,\n any,\n any\n >,\n } as any);\n });\n }\n if (\n mutationEffectOptions.optimisticPatch ||\n mutationEffectOptions.patch\n ) {\n untracked(() => {\n setAllPatchFromMutationOnQueryValue({\n mutationStatus,\n queryResourceTarget: queryTargeted as any,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource:\n mutationResource as unknown as CraftResourceRef<any, any>,\n mutationParamsSrc,\n mutationIdentifier: mutationIdentifier,\n mutationResources: mutationTargeted as any,\n });\n });\n }\n },\n );\n },\n );\n });\n}\n","import { WritableSignal } from '@angular/core';\nimport {\n ResourceByIdLikeMutationRef,\n ResourceLikeMutationRef,\n} from './mutation';\nimport { ResourceByIdLikeQueryRef, ResourceLikeQueryRef } from './query';\nimport { InsertionParams, QueryDeclarativeEffect } from './query.core';\nimport { ResourceByIdRef } from './resource-by-id';\nimport { reactOnMutationEffect } from './util/react-on-mutation-effect';\nimport { InternalType } from './util/types/util.type';\n\n/**\n * Creates an insertion function that makes a query react to mutation state changes.\n *\n * This insertion enables declarative synchronization between queries and mutations, allowing you to:\n * - Optimistically update query data when a mutation starts (before server response)\n * - Update query data when a mutation completes successfully\n * - Patch specific fields in query data based on mutation parameters\n * - Reload queries when mutations complete\n * - Filter which query instances should react (when using identifiers)\n *\n * @remarks\n * This is particularly useful for:\n * - **Optimistic UI updates**: Show changes immediately while the mutation is processing\n * - **Cache synchronization**: Keep local query cache in sync with server state after mutations\n * - **Selective updates**: Update only relevant query instances based on identifiers\n * - **Complex state management**: Coordinate multiple queries reacting to the same mutation\n *\n * @param mutation - The mutation to react to. Can be either:\n * - A standard mutation (ResourceLikeMutationRef)\n * - A mutation with identifier for grouped instances (ResourceByIdLikeMutationRef)\n * @param mutationEffectOptions - Configuration for how the query should react:\n * - `optimisticUpdate`: Function to update query state immediately when mutation starts (loading state)\n * - `update`: Function to update query state when mutation completes (resolved state)\n * - `optimisticPatch`: Object mapping query fields to mutation values for optimistic updates\n * - `patch`: Object mapping query fields to mutation values for final updates\n * - `reload`: Configuration to reload the query when mutation reaches specific states\n * - `filter`: Function to determine which query instances should react (required when using identifiers)\n *\n * @returns An insertion function that can be passed to query() to enable the reactive behavior\n *\n * @example\n * Basic optimistic update with patch\n * ```ts\n * const updateUserMutation = mutation({\n * method: (data: { id: string; name: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * const userQuery = query(\n * {\n * params: () => ({ userId: currentUserId() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateUserMutation, {\n * // Optimistically update the name while mutation is loading\n * optimisticPatch: {\n * name: ({ mutationParams }) => mutationParams.name,\n * },\n * // Apply final update when mutation resolves\n * patch: {\n * name: ({ mutationParams }) => mutationParams.name,\n * },\n * })\n * );\n *\n * // When mutation is triggered, query updates immediately (optimistic)\n * updateUserMutation.mutate({ id: '123', name: 'New Name' });\n * // userQuery.value().name is now 'New Name' (optimistic)\n *\n * // When mutation completes, patch confirms the change\n * // userQuery.value().name remains 'New Name' (confirmed)\n * ```\n *\n * @example\n * Full state update on mutation completion\n * ```ts\n * const deleteTodoMutation = mutation({\n * method: (todoId: string) => ({ todoId }),\n * loader: async ({ params }) => {\n * await fetch(`/api/todos/${params.todoId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * });\n *\n * const todosQuery = query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json(); // Returns Todo[]\n * },\n * },\n * insertReactOnMutation(deleteTodoMutation, {\n * // Remove the deleted todo from the list optimistically\n * optimisticUpdate: ({ queryResource, mutationParams }) => {\n * const currentTodos = queryResource.value() ?? [];\n * return currentTodos.filter(todo => todo.id !== mutationParams.todoId);\n * },\n * // Confirm the deletion when mutation resolves\n * update: ({ queryResource, mutationParams }) => {\n * const currentTodos = queryResource.value() ?? [];\n * return currentTodos.filter(todo => todo.id !== mutationParams.todoId);\n * },\n * })\n * );\n * ```\n *\n * @example\n * Reload query after mutation\n * ```ts\n * const createPostMutation = mutation({\n * method: (data: { title: string; content: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * const postsQuery = query(\n * {\n * params: () => ({ page: 1 }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts?page=${params.page}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(createPostMutation, {\n * // Reload the posts list when mutation completes\n * reload: {\n * onMutationResolved: true, // Reload on success\n * },\n * })\n * );\n *\n * // When mutation completes, postsQuery automatically reloads\n * createPostMutation.mutate({ title: 'New Post', content: 'Content' });\n * ```\n *\n * @example\n * Filtered updates with identifiers\n * ```ts\n * const updatePostMutation = mutation({\n * method: (data: { postId: string; title: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts/${params.postId}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * const postsQuery = query(\n * {\n * params: () => currentPostId(),\n * identifier: (params) => params, // params is the postId\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts/${params}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updatePostMutation, {\n * // Only update the query instance that matches the mutation's postId\n * filter: ({ queryIdentifier, mutationParams }) =>\n * queryIdentifier === mutationParams.postId,\n * patch: {\n * title: ({ mutationParams }) => mutationParams.title,\n * },\n * })\n * );\n *\n * // Only the query instance for post '123' will be updated\n * updatePostMutation.mutate({ postId: '123', title: 'Updated Title' });\n * console.log(postsQuery.select('123')?.value()?.title); // 'Updated Title'\n * console.log(postsQuery.select('456')?.value()?.title); // unchanged\n * ```\n *\n * @example\n * Complex nested field updates\n * ```ts\n * const updateUserProfileMutation = mutation({\n * method: (data: { userId: string; profile: { bio: string; avatar: string } }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}/profile`, {\n * method: 'PATCH',\n * body: JSON.stringify(params.profile),\n * });\n * return response.json();\n * },\n * });\n *\n * const userQuery = query(\n * {\n * params: () => ({ userId: currentUserId() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json(); // Returns { id, name, profile: { bio, avatar, ... } }\n * },\n * },\n * insertReactOnMutation(updateUserProfileMutation, {\n * optimisticPatch: {\n * 'profile.bio': ({ mutationParams }) => mutationParams.profile.bio,\n * 'profile.avatar': ({ mutationParams }) => mutationParams.profile.avatar,\n * },\n * })\n * );\n *\n * // Nested fields are updated optimistically\n * updateUserProfileMutation.mutate({\n * userId: '123',\n * profile: { bio: 'New bio', avatar: 'new-avatar.jpg' }\n * });\n * ```\n */\nexport function insertReactOnMutation<\n QueryResourceState extends object | undefined,\n QueryResourceParams,\n QueryResourceArgsParams,\n QueryIsMethod extends boolean,\n QuerySourceParams,\n QueryGroupIdentifier,\n QueryInsertions,\n MutationResourceState,\n MutationResourceParams,\n MutationResourceArgsParams,\n MutationIsMethod,\n MutationSourceParams,\n MutationGroupIdentifier,\n MutationInsertions,\n>(\n mutation:\n | ResourceLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions\n >\n | ResourceByIdLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions,\n MutationGroupIdentifier\n >,\n mutationEffectOptions: QueryDeclarativeEffect<{\n query: InternalType<\n NoInfer<QueryResourceState>,\n NoInfer<QueryResourceParams>,\n NoInfer<QueryResourceArgsParams>,\n [unknown] extends [NoInfer<QueryGroupIdentifier>] ? false : true,\n NoInfer<QueryIsMethod>,\n NoInfer<QueryInsertions>,\n NoInfer<QueryGroupIdentifier>,\n NoInfer<QuerySourceParams>\n >;\n mutation: InternalType<\n NoInfer<MutationResourceState>,\n NoInfer<MutationResourceParams>,\n NoInfer<MutationResourceArgsParams>,\n [unknown] extends [MutationGroupIdentifier] ? false : true,\n NoInfer<MutationIsMethod>,\n NoInfer<MutationInsertions>,\n NoInfer<MutationGroupIdentifier>,\n NoInfer<MutationSourceParams>\n >;\n }>,\n) {\n return (\n context:\n | InsertionParams<\n QueryResourceState,\n QueryResourceParams,\n QueryInsertions\n >\n | {\n // ! avoid to use InsertionByIdParams it is broking the typing inference\n resourceById: ResourceByIdRef<\n QueryGroupIdentifier & string,\n QueryResourceState,\n QueryResourceParams\n >;\n resourceParamsSrc: WritableSignal<QueryResourceParams | undefined>;\n identifier: (\n params: NonNullable<QueryResourceParams>,\n ) => QueryGroupIdentifier;\n insertions: keyof QueryInsertions extends string\n ? QueryInsertions\n : never;\n },\n ) => {\n return reactOnMutationEffect(\n {\n queryTargeted: ('resource' in context\n ? context.resource\n : context.resourceById) as unknown as\n | ResourceLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions\n >\n | ResourceByIdLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions,\n QueryGroupIdentifier\n >,\n mutationTargeted: mutation,\n },\n mutationEffectOptions,\n );\n };\n}\n","import { computed } from '@angular/core';\nimport { InsertionByIdParams } from './query.core';\n\n/**\n * Provides placeholder data during pagination transitions for a smoother user experience.\n *\n * When navigating between pages, this insertion shows the previous page's data while\n * the new page is loading, avoiding empty states during transitions.\n *\n * @returns An object containing:\n * - `currentPageData`: Signal with the current page data or placeholder data during loading\n * - `currentPageStatus`: Signal with the ResourceStatus of the current page\n * - `isPlaceHolderData`: Signal indicating if placeholder data is being shown\n * - `currentIdentifier`: Signal with the current page identifier\n *\n * @example\n * ```typescript\n * const pagination = signal(1);\n *\n * const userQuery = query(\n * {\n * params: pagination,\n * identifier: (params) => '' + params,\n * loader: async ({ params: page }) => fetchUsers(page),\n * },\n * insertPaginationPlaceholderData,\n * );\n *\n * // Access the data (or placeholder during loading)\n * const data = userQuery.currentPageData();\n *\n * // Check if showing placeholder\n * const isPlaceholder = userQuery.isPlaceHolderData();\n * ```\n */\nexport const insertPaginationPlaceholderData = <\n QueryResourceState extends object | undefined,\n QueryResourceParams,\n QueryResourceArgsParams,\n QueryIsMethod extends boolean,\n QuerySourceParams,\n QueryGroupIdentifier extends string,\n QueryInsertions,\n PreviousInsertionsOutputs,\n>({\n resourceById,\n resourceParamsSrc,\n identifier,\n}: InsertionByIdParams<\n QueryGroupIdentifier,\n QueryResourceState,\n QueryResourceParams,\n PreviousInsertionsOutputs\n>) => {\n let previousPageKey: QueryGroupIdentifier | undefined;\n const showPlaceHolderData = computed(() => {\n const page = resourceParamsSrc();\n const resources = resourceById();\n const pageKey = page ? identifier(page) : undefined;\n if (!pageKey) {\n return false;\n }\n const currentResource = resources[pageKey];\n // true if loading and previousPage is used\n if (\n currentResource?.status() === 'loading' &&\n !currentResource?.value() &&\n previousPageKey !== undefined &&\n resources[previousPageKey]\n ) {\n return true;\n }\n return false;\n });\n return {\n currentPageData: computed(() => {\n const page = resourceParamsSrc();\n\n const resources = resourceById();\n const pageKey = page ? identifier(page) : undefined;\n if (!pageKey) {\n return;\n }\n const currentResource = resources[pageKey];\n\n if (showPlaceHolderData()) {\n return resources[previousPageKey]?.hasValue()\n ? resources[previousPageKey]?.value()\n : undefined;\n }\n previousPageKey = pageKey;\n return currentResource?.value();\n }),\n currentPageStatus: computed(() => {\n const page = resourceParamsSrc();\n const resources = resourceById();\n if (!page) {\n return 'idle' as const; // avoid to handle the undefined check\n }\n const pageKey = identifier(page);\n const currentResource = resources[pageKey];\n return currentResource?.status() ?? ('idle' as const);\n }),\n isPlaceHolderData: showPlaceHolderData,\n currentIdentifier: computed(() => {\n const page = resourceParamsSrc();\n if (!page) {\n return '' as QueryGroupIdentifier;\n }\n return identifier(page);\n }),\n };\n};\n","import { Injectable } from '@angular/core';\n\n/**\n * Global service for managing persistence operations.\n *\n * This service provides a centralized way to clear all cached data stored in localStorage\n * by the ng-craft library. It's particularly useful when a user logs out, ensuring all\n * cached queries, mutations, and other persisted data are completely removed.\n *\n * @example\n * ```typescript\n * import { GlobalPersisterHandlerService } from '@craft-ng/core';\n *\n * export class AppComponent {\n * constructor(private persisterHandler: GlobalPersisterHandlerService) {}\n *\n * logout() {\n * // Clear all ng-craft cached data from localStorage\n * this.persisterHandler.clearAllCache();\n * // Proceed with logout logic...\n * }\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class GlobalPersisterHandlerService {\n /**\n * Clears all cached data from localStorage that was created by ng-craft.\n *\n * This method scans all keys in localStorage and removes any key that starts\n * with the 'ng-craft-' prefix. This ensures a complete cleanup of all persisted\n * queries, mutations, and other cached data.\n *\n * **Use cases:**\n * - User logout: Remove all user-specific cached data\n * - Data reset: Clear all cached data to force fresh data loading\n * - Privacy: Ensure no data remains in localStorage after user session\n *\n * @example\n * ```typescript\n * // In a logout handler\n * logout() {\n * this.persisterHandler.clearAllCache();\n * this.router.navigate(['/login']);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Force refresh all data\n * refreshAllData() {\n * this.persisterHandler.clearAllCache();\n * window.location.reload();\n * }\n * ```\n */\n clearAllCache(): void {\n const keysToRemove: string[] = [];\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith('ng-craft-')) {\n keysToRemove.push(key);\n }\n }\n\n keysToRemove.forEach((key) => localStorage.removeItem(key));\n }\n}\n","/**\n * Type to extract the identifier from an entity\n */\nexport type IdSelector<Entity, Key = string | number> = (entity: Entity) => Key;\n\n/**\n * Type for partial updates\n */\nexport type Update<T, K = string | number> = {\n id: K;\n changes: Partial<T>;\n};\n\nexport type EntitiesUtilBrand<Name> = { __brand: Name };\n\n/**\n * Helper function to get the default identifier.\n * For primitives (string | number), the entity itself is used as the identifier.\n * For objects with an `id` property, the `id` property is used.\n */\nfunction getDefaultIdentifier<T, K>(): IdSelector<T, K> {\n return (e: T) => {\n if (typeof e === 'string' || typeof e === 'number') {\n return e as unknown as K;\n }\n return (e as T & { id: K }).id;\n };\n}\n\n/**\n * Removes all elements from the list\n */\nexport function removeAll<T>(): T[] & EntitiesUtilBrand<'removeAll'> {\n return [] as unknown as T[] & EntitiesUtilBrand<'removeAll'>;\n}\n\n/**\n * Adds an element to the end of the list\n */\nexport function addOne<T>({\n entity,\n entities,\n}: {\n entity: T;\n entities: T[];\n}): T[] & EntitiesUtilBrand<'addOne'> {\n return [...entities, entity] as T[] & EntitiesUtilBrand<'addOne'>;\n}\n\n/**\n * Adds multiple elements to the end of the list\n */\nexport function addMany<T>({\n newEntities,\n entities,\n}: {\n newEntities: T[];\n entities: T[];\n}): T[] & EntitiesUtilBrand<'addMany'> {\n return [...entities, ...newEntities] as T[] & EntitiesUtilBrand<'addMany'>;\n}\n\n/**\n * Replaces the entire list with new elements\n */\nexport function setAll<T>({\n newEntities,\n}: {\n newEntities: T[];\n}): T[] & EntitiesUtilBrand<'setAll'> {\n return [...newEntities] as T[] & EntitiesUtilBrand<'setAll'>;\n}\n\n/**\n * Replaces or adds an element (based on id).\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function setOne<T extends string | number>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'setOne'>;\nexport function setOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setOne'>;\nexport function setOne<T, K = string | number>(params: {\n entity: T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setOne'>;\nexport function setOne<T, K = string | number>({\n entity,\n entities,\n identifier,\n}: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const id = getId(entity);\n const index = entities.findIndex((e) => getId(e) === id);\n\n if (index === -1) {\n return [...entities, entity] as T[] & EntitiesUtilBrand<'setOne'>;\n }\n\n return entities.map((e, i) => (i === index ? entity : e)) as T[] &\n EntitiesUtilBrand<'setOne'>;\n}\n\n/**\n * Replaces or adds multiple elements (based on id).\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function setMany<T extends string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'setMany'>;\nexport function setMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setMany'>;\nexport function setMany<T, K = string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setMany'>;\nexport function setMany<T, K = string | number>({\n newEntities,\n entities,\n identifier,\n}: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const entity of newEntities) {\n result = setOne({ entity, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'setMany'>;\n}\n\n/**\n * Partially updates an existing element.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function updateOne<T extends string | number>(params: {\n update: Update<T, T>;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'updateOne'>;\nexport function updateOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n update: Update<T, K>;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateOne'>;\nexport function updateOne<T, K = string | number>(params: {\n update: Update<T, K>;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateOne'>;\nexport function updateOne<T, K = string | number>({\n update,\n entities,\n identifier,\n}: {\n update: Update<T, K>;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const index = entities.findIndex((e) => getId(e) === update.id);\n\n if (index === -1) {\n return entities as T[] & EntitiesUtilBrand<'updateOne'>;\n }\n\n return entities.map((e, i) =>\n i === index ? { ...e, ...update.changes } : e,\n ) as T[] & EntitiesUtilBrand<'updateOne'>;\n}\n\n/**\n * Partially updates multiple existing elements.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function updateMany<T extends string | number>(params: {\n updates: Update<T, T>[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'updateMany'>;\nexport function updateMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n updates: Update<T, K>[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateMany'>;\nexport function updateMany<T, K = string | number>(params: {\n updates: Update<T, K>[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateMany'>;\nexport function updateMany<T, K = string | number>({\n updates,\n entities,\n identifier,\n}: {\n updates: Update<T, K>[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const update of updates) {\n result = updateOne({ update, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'updateMany'>;\n}\n\n/**\n * Updates an element if it exists, otherwise adds it.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function upsertOne<T extends string | number>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'upsertOne'>;\nexport function upsertOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertOne'>;\nexport function upsertOne<T, K = string | number>(params: {\n entity: T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertOne'>;\nexport function upsertOne<T, K = string | number>({\n entity,\n entities,\n identifier,\n}: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const id = getId(entity);\n const index = entities.findIndex((e) => getId(e) === id);\n\n if (index === -1) {\n return [...entities, entity] as T[] & EntitiesUtilBrand<'upsertOne'>;\n }\n\n // For primitives, just replace; for objects, merge\n const isPrimitive = typeof entity === 'string' || typeof entity === 'number';\n return entities.map((e, i) =>\n i === index ? (isPrimitive ? entity : { ...e, ...entity }) : e,\n ) as T[] & EntitiesUtilBrand<'upsertOne'>;\n}\n\n/**\n * Updates multiple elements if they exist, otherwise adds them.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function upsertMany<T extends string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'upsertMany'>;\nexport function upsertMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertMany'>;\nexport function upsertMany<T, K = string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertMany'>;\nexport function upsertMany<T, K = string | number>({\n newEntities,\n entities,\n identifier,\n}: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const entity of newEntities) {\n result = upsertOne({ entity, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'upsertMany'>;\n}\n\n/**\n * Removes an element by its id.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function removeOne<T extends string | number>(params: {\n id: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'removeOne'>;\nexport function removeOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n id: K;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeOne'>;\nexport function removeOne<T, K = string | number>(params: {\n id: K;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeOne'>;\nexport function removeOne<T, K = string | number>({\n id,\n entities,\n identifier,\n}: {\n id: K;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n return entities.filter((e) => getId(e) !== id) as T[] &\n EntitiesUtilBrand<'removeOne'>;\n}\n\n/**\n * Removes multiple elements by their ids.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function removeMany<T extends string | number>(params: {\n ids: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'removeMany'>;\nexport function removeMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n ids: K[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeMany'>;\nexport function removeMany<T, K = string | number>(params: {\n ids: K[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeMany'>;\nexport function removeMany<T, K = string | number>({\n ids,\n entities,\n identifier,\n}: {\n ids: K[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const idSet = new Set(ids);\n return entities.filter((e) => !idSet.has(getId(e))) as T[] &\n EntitiesUtilBrand<'removeMany'>;\n}\n\n/**\n * Toggles an element: removes it if it exists, adds it if it doesn't.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function toggleOne<T extends string | number>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'toggleOne'>;\nexport function toggleOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleOne'>;\nexport function toggleOne<T, K = string | number>(params: {\n entity: T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleOne'>;\nexport function toggleOne<T, K = string | number>({\n entity,\n entities,\n identifier,\n}: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const id = getId(entity);\n const exists = entities.some((e) => getId(e) === id);\n\n if (exists) {\n return entities.filter((e) => getId(e) !== id) as T[] &\n EntitiesUtilBrand<'toggleOne'>;\n }\n return [...entities, entity] as T[] & EntitiesUtilBrand<'toggleOne'>;\n}\n\n/**\n * Toggles multiple elements: removes them if they exist, adds them if they don't.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function toggleMany<T extends string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'toggleMany'>;\nexport function toggleMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleMany'>;\nexport function toggleMany<T, K = string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleMany'>;\nexport function toggleMany<T, K = string | number>({\n newEntities,\n entities,\n identifier,\n}: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const entity of newEntities) {\n result = toggleOne({ entity, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'toggleMany'>;\n}\n\n/**\n * Applies a transformation function to all elements\n */\nexport function map<T>({\n mapFn,\n entities,\n}: {\n mapFn: (entity: T) => T;\n entities: T[];\n}): T[] & EntitiesUtilBrand<'map'> {\n return entities.map(mapFn) as T[] & EntitiesUtilBrand<'map'>;\n}\n\n/**\n * Applies a transformation function to a single element by its id.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function mapOne<T extends string | number>(params: {\n id: T;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'mapOne'>;\nexport function mapOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n id: K;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'mapOne'>;\nexport function mapOne<T, K = string | number>(params: {\n id: K;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'mapOne'>;\nexport function mapOne<T, K = string | number>({\n id,\n mapFn,\n entities,\n identifier,\n}: {\n id: K;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'mapOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n return entities.map((e) => (getId(e) === id ? mapFn(e) : e)) as T[] &\n EntitiesUtilBrand<'mapOne'>;\n}\n\n/**\n * Returns the total count of entities\n */\nexport function computedTotal<T>({ entities }: { entities: T[] }): number {\n return entities.length;\n}\n\n/**\n * Returns all ids from the entities list.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function computedIds<T extends string | number>(params: {\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'computedIds'>;\nexport function computedIds<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): K[] & EntitiesUtilBrand<'computedIds'>;\nexport function computedIds<T, K = string | number>(params: {\n entities: T[];\n identifier: IdSelector<T, K>;\n}): K[] & EntitiesUtilBrand<'computedIds'>;\nexport function computedIds<T, K = string | number>({\n entities,\n identifier,\n}: {\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): K[] & EntitiesUtilBrand<'computedIds'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n return entities.map(getId) as K[] & EntitiesUtilBrand<'computedIds'>;\n}\n","import { linkedSignal, untracked, WritableSignal } from '@angular/core';\n\n/**\n * Options to control when a sync reaction callback is executed.\n */\ntype SyncOptions = {\n /**\n * If `true`, the callback is executed only during initialization\n * and will be ignored on subsequent source changes.\n */\n onInitOnly?: boolean;\n /**\n * If `true`, the callback is executed during initialization\n * AND on subsequent source changes.\n */\n onInitToo?: boolean;\n};\n\n/**\n * Creates a writable signal that reacts to changes in other signals (sources).\n *\n * Built on top of Angular's `linkedSignal`, it compares source references to determine\n * if a reaction callback should be called. When a source's reference changes (`!==`),\n * the associated callback is executed with the new value and the current state.\n *\n * **Important:** During the same reactive cycle, multiple callbacks can be triggered.\n * The order of reactions in the object matters - callbacks are executed in declaration order.\n * Place reactions that should run first at the top.\n *\n * @param initialValue - The initial value of the signal\n * @param reactionBuilder - A function that receives a `sync` helper and returns an object\n * of named reactions. Each reaction defines a source signal and a computation callback.\n *\n * @returns A `WritableSignal` that can be read, set, or updated manually, while also\n * reacting to source changes.\n *\n * @example\n * ```typescript\n * const selectedRows = reactiveWritableSignal([] as string[], (sync) => ({\n * resetOnPageResolved: sync(\n * pageStatus, // Signal<ResourceStatus>\n * ({ params, current }) => (params === 'resolved' ? [] : current),\n * ),\n * removeDeleted: sync(\n * deletedIds, // Signal<string[]>\n * ({ params, current }) => current.filter(id => !params.includes(id)),\n * ),\n * }));\n * ```\n *\n * @see SyncOptions for `onInitOnly` and `onInitToo` options\n */\ntype ReactionEntry<State, Params> = {\n source: () => Params;\n computation: (payload: {\n params: NoInfer<Params>;\n current: NoInfer<State>;\n }) => NoInfer<State>;\n options?: SyncOptions;\n};\n\ntype SourcesSnapshot = Map<string, unknown>;\n\nexport function reactiveWritableSignal<State>(\n initialValue: State,\n reactionBuilder: (\n sync: <Params>(\n source: () => Params,\n computation: (payload: {\n params: NoInfer<Params>;\n current: NoInfer<State>;\n }) => NoInfer<State>,\n options?: SyncOptions,\n ) => ReactionEntry<State, Params>,\n ) => Record<string, ReactionEntry<State, any>>,\n): WritableSignal<State> {\n // Helper function to create reaction entries\n const sync = <Params>(\n source: () => Params,\n computation: (payload: {\n params: NoInfer<Params>;\n current: NoInfer<State>;\n }) => NoInfer<State>,\n options?: SyncOptions,\n ): ReactionEntry<State, Params> => ({\n source,\n computation,\n options,\n });\n\n // Build all reactions\n const reactions = reactionBuilder(sync);\n\n // Create a snapshot of all source values\n const getSourcesSnapshot = (): SourcesSnapshot => {\n const snapshot = new Map<string, unknown>();\n for (const [name, reaction] of Object.entries(reactions)) {\n snapshot.set(name, reaction.source());\n }\n return snapshot;\n };\n\n // Use linkedSignal to track source changes\n const sig = linkedSignal<SourcesSnapshot, State>({\n source: getSourcesSnapshot,\n computation: (currentSnapshot, previous) => {\n const isInitialization = !previous;\n let currentState = isInitialization ? initialValue : previous.value;\n const previousSnapshot = previous?.source;\n\n untracked(() => {\n // Check which sources changed (by reference) and run their computations\n for (const [name, reaction] of Object.entries(reactions)) {\n const currentValue = currentSnapshot.get(name);\n const previousValue = previousSnapshot?.get(name);\n const options = reaction.options;\n\n const hasSourceChanged = currentValue !== previousValue;\n\n // Determine if we should run the computation\n let shouldRun = false;\n\n if (isInitialization) {\n // During initialization: run if onInitOnly or onInitToo\n if (options?.onInitOnly || options?.onInitToo) {\n shouldRun = true;\n }\n } else {\n // After initialization: run if source changed AND not onInitOnly\n if (hasSourceChanged && !options?.onInitOnly) {\n shouldRun = true;\n }\n }\n\n if (shouldRun) {\n currentState = reaction.computation({\n params: currentValue,\n current: currentState,\n });\n }\n }\n });\n\n return currentState;\n },\n });\n\n return sig;\n}\n","import {\n DestroyRef,\n EventEmitter,\n inject,\n Signal,\n signal,\n} from '@angular/core';\n\nexport type SourceSubscribe<T> = {\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n};\n\nexport type Source$<T> = {\n emit: (value: T) => void;\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n asReadonly: () => ReadonlySource$<T>;\n preserveLastValue: () => {\n emit: (value: T) => void;\n subscribe: (callback: (value: T) => void) => void;\n asReadonly: () => {\n subscribe: (callback: (value: T) => void) => void;\n value: Signal<T | undefined>;\n };\n value: Signal<T | undefined>;\n };\n value: Signal<T | undefined>;\n};\n\nexport type ReadonlySource$<T> = {\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n value: Signal<T | undefined>;\n};\n\nexport function source$<T>(): Source$<T> {\n const sourceRef$ = new EventEmitter<T>();\n const destroyRef = inject(DestroyRef);\n\n const sourceAsSignal = signal<T | undefined>(undefined);\n\n return {\n emit: (value: T) => {\n sourceRef$.emit(value);\n sourceAsSignal.set(value);\n },\n subscribe: (callback: (value: T) => void) => sourceRef$.subscribe(callback),\n preserveLastValue: () => {\n const sourceWithLastValueRef = new EventEmitter<T>();\n const subscriptionWithLastLastValue = sourceRef$.subscribe((value) => {\n sourceWithLastValueRef.emit(value);\n });\n\n destroyRef.onDestroy(() => subscriptionWithLastLastValue.unsubscribe());\n\n return {\n emit: (value: T) => {\n sourceWithLastValueRef.emit(value);\n sourceAsSignal.set(value);\n },\n subscribe: (callback: (value: T) => void) => {\n sourceWithLastValueRef.subscribe(callback);\n sourceWithLastValueRef.emit(sourceAsSignal());\n },\n asReadonly: () => ({\n subscribe: (callback: (value: T) => void) => {\n sourceWithLastValueRef.subscribe(callback);\n sourceWithLastValueRef.emit(sourceAsSignal());\n },\n value: sourceAsSignal.asReadonly(),\n }),\n value: sourceAsSignal.asReadonly(),\n };\n },\n value: sourceAsSignal.asReadonly(),\n asReadonly: () => ({\n subscribe: (callback: (value: T) => void) =>\n sourceRef$.subscribe(callback),\n value: sourceAsSignal.asReadonly(),\n }),\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"craft-ng-core.mjs","sources":["../../../../libs/core/src/lib/util/util.ts","../../../../libs/core/src/lib/after-recomputation.ts","../../../../libs/core/src/lib/preserved-resource.ts","../../../../libs/core/src/lib/util/resource-by-id-changes-tracker.util.ts","../../../../libs/core/src/lib/resource-by-id.ts","../../../../libs/core/src/lib/craft-resource.ts","../../../../libs/core/src/lib/async-process.ts","../../../../libs/core/src/lib/computed-source.ts","../../../../libs/core/src/lib/signal-proxy.ts","../../../../libs/core/src/lib/craft.ts","../../../../libs/core/src/lib/craft-async-process.ts","../../../../libs/core/src/lib/craft-computed.ts","../../../../libs/core/src/lib/craft-inject.ts","../../../../libs/core/src/lib/craft-inputs.ts","../../../../libs/core/src/lib/craft-mutations.ts","../../../../libs/core/src/lib/craft-query-param.ts","../../../../libs/core/src/lib/craft-query-params.ts","../../../../libs/core/src/lib/craft-query.ts","../../../../libs/core/src/lib/craft-set-all-queries-params-standalone.ts","../../../../libs/core/src/lib/craft-sources.ts","../../../../libs/core/src/lib/craft-state.ts","../../../../libs/core/src/lib/util/persister.util.ts","../../../../libs/core/src/lib/util/explicit-effect.ts","../../../../libs/core/src/lib/util/types/util.ts","../../../../libs/core/src/lib/local-storage-persister.ts","../../../../libs/core/src/lib/insert-local-storage-persister.ts","../../../../libs/core/src/lib/linked-source.ts","../../../../libs/core/src/lib/mutation.ts","../../../../libs/core/src/lib/query-param.ts","../../../../libs/core/src/lib/query.ts","../../../../libs/core/src/lib/signal-source.ts","../../../../libs/core/src/lib/source-from-event.ts","../../../../libs/core/src/lib/stacked-source.ts","../../../../libs/core/src/lib/state.ts","../../../../libs/core/src/lib/to-source.ts","../../../../libs/core/src/lib/util/util.type.ts","../../../../libs/core/src/lib/util/update-state.util.ts","../../../../libs/core/src/lib/query.core.ts","../../../../libs/core/src/lib/util/react-on-mutation-effect.ts","../../../../libs/core/src/lib/insert-react-on-mutation.ts","../../../../libs/core/src/lib/insert-pagination-placeholder-data.ts","../../../../libs/core/src/lib/global-persister-handler.service.ts","../../../../libs/core/src/lib/util/entities-util.ts","../../../../libs/core/src/lib/reactive-writable-signal.ts","../../../../libs/core/src/lib/source$.ts","../../../../libs/core/src/lib/from-event-to-source$.ts","../../../../libs/core/src/lib/on$.ts","../../../../libs/core/src/craft-ng-core.ts"],"sourcesContent":["import { effect, untracked, WritableSignal } from '@angular/core';\nimport { ReadonlySource } from './source.type';\n\nexport const SourceBrand = Symbol('SourceBrand');\n\nexport const SourceBranded = {\n [SourceBrand]: true as const,\n};\n\nexport type SourceBranded = {\n [SourceBrand]: true;\n};\n\n/**\n * Works for Source and ReadonlySource\n */\nexport function isSource(value: any): boolean {\n return value && SourceBrand in value;\n}\n\nexport type SourceBrand = typeof SourceBrand;\n\nexport function capitalize<S extends string>(str: S): Capitalize<S> {\n return (str.charAt(0).toUpperCase() + str.slice(1)) as Capitalize<S>;\n}\n\nexport function createMethodHandlers<State>(\n methodsData:\n | Record<\n string,\n ((...args: any[]) => NoInfer<State>) | ReadonlySource<State>\n >\n | undefined,\n state: WritableSignal<State>,\n options?: {\n onStateChange?: (newValue: State) => void;\n },\n) {\n const { methodsConnectedToSource, methods } = Object.entries(\n methodsData ?? {},\n ).reduce(\n (acc, [methodName, methodValue]) => {\n if (isSource(methodValue)) {\n acc.methodsConnectedToSource.push(\n methodValue as ReadonlySource<unknown>,\n );\n return acc;\n }\n acc.methods[methodName] = methodValue as Function;\n return acc;\n },\n {\n methodsConnectedToSource: [],\n methods: {},\n } as {\n methodsConnectedToSource: ReadonlySource<unknown>[];\n methods: Record<string, Function>;\n },\n );\n\n const finalMethods = Object.entries(methods ?? {}).reduce(\n (acc, [methodName, method]) => {\n acc[methodName] = (...args: any[]) => {\n const result = method(...args);\n state.set(result);\n options?.onStateChange?.(result);\n };\n return acc;\n },\n {} as Record<string, Function>,\n );\n\n methodsConnectedToSource.forEach((sourceSignal) => {\n effect(() => {\n const newValue = sourceSignal();\n untracked(() => {\n if (newValue !== undefined) {\n state.set(newValue as NoInfer<State>);\n }\n });\n });\n });\n return finalMethods;\n}\n","import { effect, signal, untracked } from '@angular/core';\nimport { SignalSource } from './signal-source';\nimport { ReadonlySource } from './util/source.type';\nimport { SourceBranded } from './util/util';\n\n/**\n * Creates a derived readonly source that transforms source emissions through a callback function.\n *\n * This function binds queries, mutations, and async methods to sources for automatic execution by:\n * - Listening to source emissions and computing new values\n * - Providing a readonly source suitable for method binding\n * - Maintaining reactivity through Angular's effect system\n * - Enabling source-based triggering patterns\n *\n * @remarks\n * **Primary Use Case:**\n * Bind queries/mutations/async methods to sources for automatic execution:\n * ```ts\n * method: afterRecomputation(mySource, (data) => data)\n * ```\n * This pattern makes queries/mutations execute automatically when the source emits.\n *\n * **Execution Flow:**\n * 1. Source emits a value via `source.set(value)`\n * 2. afterRecomputation callback transforms the value\n * 3. Resulting readonly source emits the transformed value\n * 4. Bound query/mutation/async method executes with the new value\n *\n * **Difference from computedSource:**\n * - `afterRecomputation`: Designed for binding to method parameters\n * - `computedSource`: General-purpose source transformation\n * - Both transform source values, but afterRecomputation is optimized for method binding\n *\n * **Common Patterns:**\n * - **Identity transformation**: `afterRecomputation(source, (x) => x)` - pass value through\n * - **Field extraction**: `afterRecomputation(source, (data) => data.id)` - extract specific field\n * - **Validation**: `afterRecomputation(source, (data) => validate(data))` - transform and validate\n * - **Mapping**: `afterRecomputation(source, (data) => mapToDto(data))` - convert to different type\n *\n * @template State - The type of values produced by the callback\n * @template SourceType - The type of values emitted by the origin source\n *\n * @param _source - The source to listen to.\n * When this source emits, the callback is invoked.\n *\n * @param callback - Function that transforms source values.\n * Receives the emitted value and returns the transformed result.\n *\n * @returns A readonly source that emits transformed values.\n * Can be used as the `method` parameter in queries, mutations, and async methods.\n *\n * @example\n * Binding a query to a source for automatic execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * userIdChange: source<string>(),\n * }),\n * craftQuery('user', ({ userIdChange }) =>\n * query({\n * method: afterRecomputation(userIdChange, (userId) => userId),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Query executes automatically when source emits\n * store.setUserIdChange('user-123');\n * // -> query loader executes with params 'user-123'\n *\n * store.setUserIdChange('user-456');\n * // -> query loader executes again with params 'user-456'\n * ```\n *\n * @example\n * Binding a mutation to a source\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * submitForm: source<{ name: string; email: string }>(),\n * }),\n * craftMutations(({ submitForm }) => ({\n * submit: mutation({\n * method: afterRecomputation(submitForm, (formData) => formData),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Mutation executes automatically when source emits\n * store.setSubmitForm({ name: 'John', email: 'john@example.com' });\n * // -> mutation loader executes with form data\n * // Note: No store.mutateSubmit method exposed (source-based)\n * ```\n *\n * @example\n * Binding async method to a source\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * searchInput: source<string>(),\n * }),\n * craftAsyncProcesses(({ searchInput }) => ({\n * search: asyncProcess({\n * method: afterRecomputation(searchInput, (term) => term),\n * loader: async ({ params }) => {\n * // Debounce at source level before setting\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Async method executes automatically\n * store.setSearchInput('query');\n * // -> search loader executes\n * ```\n *\n * @example\n * Extracting specific field from complex data\n * ```ts\n * type FormData = {\n * user: { id: string; name: string };\n * address: { city: string };\n * };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * formSubmit: source<FormData>(),\n * }),\n * craftMutations(({ formSubmit }) => ({\n * updateUser: mutation({\n * // Extract only user data\n * method: afterRecomputation(formSubmit, (data) => data.user),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Only user data is passed to mutation\n * store.setFormSubmit({\n * user: { id: 'user-1', name: 'John' },\n * address: { city: 'NYC' },\n * });\n * // -> mutation receives only { id: 'user-1', name: 'John' }\n * ```\n *\n * @example\n * Transforming data before execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * searchParams: source<{ query: string; filters: string[] }>(),\n * }),\n * craftQuery('results', ({ searchParams }) =>\n * query({\n * method: afterRecomputation(searchParams, (params) => ({\n * q: params.query.trim().toLowerCase(),\n * f: params.filters.join(','),\n * })),\n * loader: async ({ params }) => {\n * const query = new URLSearchParams(params);\n * const response = await fetch(`/api/search?${query}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Data is transformed before query execution\n * store.setSearchParams({\n * query: ' Angular ',\n * filters: ['tutorial', 'advanced'],\n * });\n * // -> query receives { q: 'angular', f: 'tutorial,advanced' }\n * ```\n *\n * @example\n * Validation and type narrowing\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * inputChange: source<string>(),\n * }),\n * craftAsyncProcesses(({ inputChange }) => ({\n * validate: asyncProcess({\n * method: afterRecomputation(inputChange, (input) => {\n * // Only proceed if input is valid\n * const trimmed = input.trim();\n * if (trimmed.length < 3) {\n * throw new Error('Input too short');\n * }\n * return trimmed;\n * }),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/validate', {\n * method: 'POST',\n * body: JSON.stringify({ input: params }),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Invalid input throws error in callback\n * store.setInputChange('ab'); // Error: Input too short\n *\n * // Valid input proceeds\n * store.setInputChange('valid input'); // Validation executes\n * ```\n *\n * @example\n * Multiple sources with different transformations\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * quickSearch: source<string>(),\n * advancedSearch: source<{ query: string; options: unknown }>(),\n * }),\n * craftQuery('searchResults', ({ quickSearch, advancedSearch }) =>\n * query({\n * method: afterRecomputation(\n * // Can combine sources at higher level\n * quickSearch, // For this example, using one source\n * (term) => ({ query: term, mode: 'quick' })\n * ),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/search', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Quick search with simple string\n * store.setQuickSearch('angular');\n * // -> query receives { query: 'angular', mode: 'quick' }\n * ```\n *\n * @example\n * Identity transformation (pass-through)\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * dataUpdate: source<{ id: string; payload: unknown }>(),\n * }),\n * craftMutations(({ dataUpdate }) => ({\n * update: mutation({\n * // Pass data through unchanged\n * method: afterRecomputation(dataUpdate, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/data/${params.id}`, {\n * method: 'PUT',\n * body: JSON.stringify(params.payload),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Data passed through unchanged\n * store.setDataUpdate({ id: 'item-1', payload: { value: 123 } });\n * // -> mutation receives exact same object\n * ```\n */\nexport function afterRecomputation<State, SourceType>(\n _source: SignalSource<SourceType>,\n callback: (source: SourceType) => State,\n): ReadonlySource<State> {\n const derivedSource = signal<State | undefined>(undefined);\n const effectRef = effect(() => {\n const sourceValue = _source();\n if (sourceValue !== undefined) {\n untracked(() => {\n const newState = callback(sourceValue);\n derivedSource.set(newState);\n });\n } else {\n derivedSource.set(undefined);\n }\n });\n return Object.assign(\n derivedSource,\n SourceBranded,\n ) as unknown as ReadonlySource<State>;\n}\n","import {\n resource,\n linkedSignal,\n ResourceOptions,\n computed,\n} from '@angular/core';\nimport {\n CraftResourceRef,\n CraftResourceRefSpecificState,\n} from './util/craft-resource-ref';\n\nexport function preservedResource<T, R>(\n config: ResourceOptions<T, R>,\n): CraftResourceRef<T | undefined, R> {\n const original = resource(config);\n const originalCopy = { ...original };\n const preserved = linkedSignal({\n source: () => ({\n //@ts-expect-error originalCopy can access to isError\n value: originalCopy.isError() ? undefined : originalCopy.value(),\n status: originalCopy.status(),\n isLoading: originalCopy.isLoading(),\n }),\n computation: (current, previous) => {\n if (current.isLoading) {\n if (previous) {\n return previous.value;\n } else {\n return config.defaultValue;\n }\n }\n return current.value;\n },\n debugName: 'preservedResource_preserved',\n });\n const state = computed(\n () => {\n return preserved();\n },\n {\n debugName: 'preservedResource_state',\n },\n ) as CraftResourceRefSpecificState<T | undefined, R>['safeValue'];\n\n if (config.defaultValue) {\n original.set(config.defaultValue);\n }\n return {\n value: preserved,\n hasValue: original.hasValue.bind(original),\n status: original.status,\n error: original.error,\n isLoading: original.isLoading,\n reload: original.reload.bind(original),\n destroy: original.destroy.bind(original),\n update: original.update.bind(original),\n set: original.set.bind(original),\n asReadonly: original.asReadonly.bind(original),\n safeValue: state,\n paramSrc: config.params,\n state,\n } as CraftResourceRef<T | undefined, R>;\n}\n","import { computed, linkedSignal, Signal } from '@angular/core';\nimport { CraftResourceRef } from './craft-resource-ref';\n\nexport type ResourceStatus =\n | 'resolved'\n | 'error'\n | 'loading'\n | 'reloading'\n | 'idle'\n | 'local';\n\ntype FullResourceStatusSnapshot<GroupIdentifier extends string> = Map<\n GroupIdentifier,\n { status: ResourceStatus; value: unknown }\n>;\n\nexport type resourceByIdChangesTrackerResult<GroupIdentifier extends string> = {\n hasChange: Signal<boolean>;\n ids: Signal<GroupIdentifier[]>;\n resolved: Signal<GroupIdentifier[]>;\n loading: Signal<GroupIdentifier[]>;\n reloading: Signal<GroupIdentifier[]>;\n error: Signal<GroupIdentifier[]>;\n onlyValueChange: Signal<GroupIdentifier[]>;\n};\n\ntype ChangesByStatus<GroupIdentifier extends string> = {\n ids: GroupIdentifier[];\n resolved: GroupIdentifier[];\n loading: GroupIdentifier[];\n reloading: GroupIdentifier[];\n error: GroupIdentifier[];\n onlyValueChange: GroupIdentifier[];\n};\n\n/**\n * Tracks the status and value changes of resources in a ResourceByIdRef.\n * Returns an object with signals for:\n * - hasChange: true when any ID has changed status or value\n * - ids: all IDs that changed (status or value)\n * - resolved: IDs that transitioned to 'resolved' status\n * - loading: IDs that transitioned to 'loading' status\n * - reloading: IDs that transitioned to 'reloading' status\n * - error: IDs that transitioned to 'error' status\n * - onlyValueChange: IDs where only the value changed (status stayed the same)\n *\n * @param resourceByIdSignal - The signal containing the resource map to track\n * @returns An object with signals for different change types\n */\nexport function resourceByIdChangesTracker<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n>(\n resourceByIdSignal: Signal<\n Partial<Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>>\n >,\n): resourceByIdChangesTrackerResult<GroupIdentifier> {\n const changes = linkedSignal<\n FullResourceStatusSnapshot<GroupIdentifier>,\n ChangesByStatus<GroupIdentifier>\n >({\n source: () => getFullStatusSnapshot(resourceByIdSignal()),\n computation: (currentSnapshot, previous) => {\n const emptyChanges: ChangesByStatus<GroupIdentifier> = {\n ids: [],\n resolved: [],\n loading: [],\n reloading: [],\n error: [],\n onlyValueChange: [],\n };\n\n if (!previous) {\n // First read - return empty arrays\n return emptyChanges;\n }\n\n const previousSnapshot = previous.source;\n const result: ChangesByStatus<GroupIdentifier> = {\n ids: [],\n resolved: [],\n loading: [],\n reloading: [],\n error: [],\n onlyValueChange: [],\n };\n\n // Find IDs that changed status or value\n for (const [id, current] of currentSnapshot.entries()) {\n const prev = previousSnapshot.get(id);\n const statusChanged = prev?.status !== current.status;\n const valueChanged = prev?.value !== current.value;\n\n if (statusChanged || valueChanged) {\n result.ids.push(id);\n\n if (statusChanged) {\n // Add to the appropriate status array\n if (current.status === 'resolved' || current.status === 'local') {\n result.resolved.push(id);\n } else if (current.status === 'loading') {\n result.loading.push(id);\n } else if (current.status === 'reloading') {\n result.reloading.push(id);\n } else if (current.status === 'error') {\n result.error.push(id);\n }\n } else if (valueChanged) {\n // Only value changed, not status\n result.onlyValueChange.push(id);\n }\n }\n }\n\n return result;\n },\n });\n\n return {\n hasChange: computed(() => changes().ids.length > 0),\n ids: computed(() => changes().ids),\n resolved: computed(() => changes().resolved),\n loading: computed(() => changes().loading),\n reloading: computed(() => changes().reloading),\n error: computed(() => changes().error),\n onlyValueChange: computed(() => changes().onlyValueChange),\n };\n}\n\nfunction getFullStatusSnapshot<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n>(\n resources: Partial<\n Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>\n >,\n): FullResourceStatusSnapshot<GroupIdentifier> {\n const snapshot = new Map<\n GroupIdentifier,\n { status: ResourceStatus; value: unknown }\n >();\n\n for (const [id, resourceRef] of Object.entries(resources) as [\n GroupIdentifier,\n CraftResourceRef<State, ResourceParams> | undefined,\n ][]) {\n if (!resourceRef) continue;\n snapshot.set(id, {\n status: resourceRef.status(),\n value: resourceRef.hasValue() ? resourceRef.value() : undefined,\n });\n }\n\n return snapshot;\n}\n","import {\n inject,\n signal,\n ResourceOptions,\n effect,\n untracked,\n Injector,\n InjectionToken,\n WritableSignal,\n computed,\n Signal,\n linkedSignal,\n} from '@angular/core';\nimport { preservedResource } from './preserved-resource';\nimport { Prettify } from './util/util.type';\nimport { CraftResourceRef } from './util/craft-resource-ref';\nimport {\n resourceByIdChangesTracker,\n resourceByIdChangesTrackerResult,\n} from './util/resource-by-id-changes-tracker.util';\n\nexport type ResourceByIdHandler<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n> = {\n /**\n * Reset all the CraftResourceRef instance stored in the ResourceByIdRef\n */\n reset: () => void;\n /**\n * Reset the CraftResourceRef instance associated with the provided id\n */\n resetResource: (id: GroupIdentifier) => void;\n /**\n * Add a new CraftResourceRef instance\n */\n add: (\n // todo pass params instead of id and create the id from the params using the identifier function\n params: ResourceParams,\n options?: {\n defaultValue?: State;\n },\n ) => CraftResourceRef<State, ResourceParams>;\n /**\n * ! The added resource may not load immediately if the global params do not match the identifier function.\n * Useful at the app initialization when the resource value is retrieved from a persister for example.\n */\n addById: (\n id: GroupIdentifier,\n options?: {\n defaultParam?: ResourceParams;\n defaultValue?: State;\n paramsFromResourceById?: CraftResourceRef<unknown, unknown>;\n },\n ) => CraftResourceRef<State, ResourceParams>;\n /**\n * Set the values of multiple resources. If a resource doesn't exist, it will be created.\n */\n set: (payload: Partial<Record<GroupIdentifier, State>>) => void;\n /**\n * Update values of multiple resources without removing existing ones.\n * If a resource doesn't exist, it will be created.\n */\n update: (\n payload: (\n state: Partial<Record<GroupIdentifier, State>>,\n ) => Partial<Record<GroupIdentifier, State>>,\n ) => void;\n /**\n * Tracks the status and value changes of resources.\n * Provides signals for hasChange, ids, resolved, loading, reloading, error, and onlyValueChange.\n */\n changes: resourceByIdChangesTrackerResult<GroupIdentifier>;\n /**\n * A computed signal that returns a record of all resource states by their group identifier.\n */\n state: Signal<Partial<Record<GroupIdentifier, State>>>;\n};\n\nexport type Identifier<ResourceParams, GroupIdentifier> = (\n request: NonNullable<ResourceParams>,\n) => GroupIdentifier;\n\nexport type ResourceByIdRef<\n GroupIdentifier extends string,\n State,\n ResourceParams,\n> = Signal<\n // expose a signal instead of a writableSignal to avoid typing conflicts\n Prettify<\n Partial<Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>>\n >\n> &\n ResourceByIdHandler<GroupIdentifier, State, ResourceParams>;\n\nexport type EqualParams<ResourceParams, GroupIdentifier extends string> =\n | 'default'\n | 'useIdentifier'\n | ((\n a: ResourceParams,\n b: ResourceParams,\n identifierFn: (params: ResourceParams) => GroupIdentifier,\n ) => boolean);\n\ntype ResourceByIdConfig<\n State,\n ResourceParams,\n GroupIdentifier extends string,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n> = Omit<ResourceOptions<State, ResourceParams>, 'params'> &\n (\n | {\n fromResourceById?: never;\n params: () => ResourceParams;\n identifier: Identifier<NoInfer<ResourceParams>, GroupIdentifier>;\n equalParams?: EqualParams<ResourceParams, GroupIdentifier>;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will kill the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n params: (\n entity: CraftResourceRef<\n NoInfer<FromObjectState>,\n NoInfer<FromObjectResourceParams>\n >,\n ) => ResourceParams;\n identifier: Identifier<NoInfer<ResourceParams>, GroupIdentifier>;\n equalParams?: EqualParams<ResourceParams, GroupIdentifier>;\n }\n );\n\nexport function resourceById<\n State,\n ResourceParams,\n GroupIdentifier extends string,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n config: ResourceByIdConfig<\n State,\n ResourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n): ResourceByIdRef<GroupIdentifier, State, ResourceParams> {\n const injector = inject(Injector);\n const { identifier, params, loader, stream, equalParams } = config;\n const fromResourceById =\n 'fromResourceById' in config ? config.fromResourceById : undefined;\n\n // maybe create a linkedSignal to enable to reset\n const resourceByGroup = signal<\n Partial<Record<GroupIdentifier, CraftResourceRef<State, ResourceParams>>>\n >({});\n\n const resourceEqualParams =\n equalParams === 'useIdentifier'\n ? (a: NonNullable<ResourceParams>, b: NonNullable<ResourceParams>) =>\n a && b && identifier(a) === identifier(b)\n : equalParams;\n\n // this effect is used to create a mapped CraftResourceRef instance\n if (!fromResourceById) {\n effect(() => {\n //@ts-expect-error TypeScript misinterpreting, params here has no parameter\n const requestValue = params();\n if (!requestValue) {\n return;\n }\n const group = identifier(requestValue);\n\n // The effect should only trigger when the request change\n const resourceByGroupValue = untracked(() => resourceByGroup());\n const groupCraftResourceRefExist = resourceByGroupValue[group];\n if (groupCraftResourceRefExist) {\n // nothing to do, the resource is already bind with the request\n return;\n }\n\n const filteredRequestByGroup = linkedSignal({\n source: params as () => ResourceParams,\n computation: (incomingRequestValue, previousGroupRequestData) => {\n if (!incomingRequestValue) {\n return incomingRequestValue;\n }\n // filter the request push a value by comparing with the current group\n if (identifier(incomingRequestValue) !== group) {\n return previousGroupRequestData?.value;\n }\n // The request push a value that concerns the current group\n return incomingRequestValue;\n },\n });\n\n //@ts-expect-error TypeScript misinterpreting\n const paramsWithEqualRule = computed(() => filteredRequestByGroup(), {\n ...(equalParams !== 'default' && { equal: resourceEqualParams }),\n });\n\n const CraftResourceRef = createDynamicResource(injector, {\n group,\n //@ts-expect-error stream and loader conflict\n resourceOptions: {\n loader,\n params: paramsWithEqualRule,\n stream,\n },\n });\n\n // attach a new instance of CraftResourceRef to the resourceByGroup\n resourceByGroup.update((state) => ({\n ...state,\n [group]: CraftResourceRef,\n }));\n });\n }\n\n const changesTracker = resourceByIdChangesTracker(resourceByGroup);\n\n const stateSignal = computed(() => {\n const resources = resourceByGroup();\n const stateRecord: Partial<Record<GroupIdentifier, State>> = {};\n for (const [key, resource] of Object.entries(resources)) {\n if (resource) {\n const craftResource = resource as CraftResourceRef<\n State,\n ResourceParams\n >;\n if (craftResource.hasValue()) {\n stateRecord[key as GroupIdentifier] = craftResource.value();\n }\n }\n }\n return stateRecord;\n });\n\n const resourcesHandler: ResourceByIdHandler<\n GroupIdentifier,\n State,\n ResourceParams\n > = {\n changes: changesTracker,\n state: stateSignal,\n reset: () => {\n Object.values(resourceByGroup()).forEach((resource) =>\n (resource as CraftResourceRef<State, ResourceParams>).destroy(),\n );\n resourceByGroup.set({});\n },\n resetResource: (id: GroupIdentifier) => {\n resourceByGroup.update((state) => {\n const newState = { ...state };\n newState[id]?.destroy();\n delete newState[id];\n return newState;\n });\n },\n set: (payload: Partial<Record<GroupIdentifier, State>>) => {\n // Remove existing keys that are not in the payload\n const currentResources = resourceByGroup();\n Object.keys(currentResources).forEach((id) => {\n if (!(id in payload)) {\n resourcesHandler.resetResource(id as GroupIdentifier);\n }\n });\n\n // Set or create resources from the payload\n Object.entries(payload).forEach(([id, value]) => {\n const existingResource = resourceByGroup()[id as GroupIdentifier];\n if (existingResource) {\n existingResource.set(value as State);\n } else {\n // If the resource doesn't exist, create it with the provided value as default\n resourcesHandler.addById(id as GroupIdentifier, {\n defaultValue: value as State,\n });\n }\n });\n },\n update: (\n payload: (\n state: Partial<Record<GroupIdentifier, State>>,\n ) => Partial<Record<GroupIdentifier, State>>,\n ) => {\n const nextState = payload(stateSignal());\n resourcesHandler.set(nextState);\n },\n add: (resourceParams, options?: { defaultValue?: State }) => {\n const group = identifier(resourceParams as any);\n if (resourceByGroup()[group]) {\n return resourceByGroup()[group] as CraftResourceRef<\n State,\n ResourceParams\n >;\n }\n\n //@ts-expect-error ! It does not handle the case when fromResourceById is provided\n const computedParam = computed(() => params() ?? resourceParams);\n const filteredGlobalParamsByGroup = linkedSignal({\n source: computedParam as () => ResourceParams,\n computation: (incomingParamsValue, previousGroupParamsData) => {\n if (!incomingParamsValue) {\n return incomingParamsValue;\n }\n // filter the request push a value by comparing with the current group\n if (identifier(incomingParamsValue) !== group) {\n return (\n (previousGroupParamsData?.value as ResourceParams) ??\n resourceParams\n );\n }\n // The request push a value that concerns the current group\n return incomingParamsValue;\n },\n });\n // ! without pulling the signal here, it is not possible to load multiples resources in the same cycle\n const _pull_filteredGlobalParamsByGroup = filteredGlobalParamsByGroup();\n const paramsWithEqualRule = computed(\n filteredGlobalParamsByGroup as Signal<NonNullable<ResourceParams>>,\n //@ts-expect-error TypeScript misinterpreting\n {\n ...(equalParams !== 'default' && {\n equal: resourceEqualParams,\n }),\n },\n );\n const CraftResourceRef = createDynamicResource(injector, {\n group,\n resourceOptions: {\n loader,\n params: paramsWithEqualRule,\n stream,\n defaultValue: options?.defaultValue,\n } as ResourceOptions<State, ResourceParams>,\n });\n resourceByGroup.update((state) => ({\n ...state,\n [group]: CraftResourceRef,\n }));\n return CraftResourceRef;\n },\n addById: (\n group,\n options?: {\n defaultValue?: State;\n defaultParam?: ResourceParams;\n paramsFromResourceById?: CraftResourceRef<unknown, unknown>;\n },\n ) => {\n // Check if the resource already exist\n if (resourceByGroup()[group]) {\n return resourceByGroup()[group] as CraftResourceRef<\n State,\n ResourceParams\n >;\n }\n const filteredGlobalParamsByGroup = linkedSignal({\n source: () =>\n params(\n options?.paramsFromResourceById as CraftResourceRef<\n FromObjectState,\n FromObjectResourceParams\n >,\n ),\n computation: (incomingParamsValue, previousGroupParamsData) => {\n if (!incomingParamsValue) {\n return incomingParamsValue ?? options?.defaultParam;\n }\n // filter the request push a value by comparing with the current group\n if (identifier(incomingParamsValue) !== group) {\n return (\n (previousGroupParamsData?.value as ResourceParams) ??\n options?.defaultParam\n );\n }\n // The request push a value that concerns the current group\n return incomingParamsValue;\n },\n });\n\n // ! without pulling the signal here, it is not possible to load multiples resources in the same cycle\n const _pull_filteredGlobalParamsByGroup = filteredGlobalParamsByGroup();\n const paramsWithEqualRule = computed(\n filteredGlobalParamsByGroup as Signal<NonNullable<ResourceParams>>,\n //@ts-expect-error TypeScript misinterpreting\n {\n ...(equalParams !== 'default' && {\n equal: resourceEqualParams,\n }),\n },\n );\n const CraftResourceRef = createDynamicResource(injector, {\n group,\n resourceOptions: {\n loader,\n params: paramsWithEqualRule,\n stream,\n defaultValue: options?.defaultValue,\n } as ResourceOptions<State, ResourceParams>,\n });\n resourceByGroup.update((state) => ({\n ...state,\n [group]: CraftResourceRef,\n }));\n return CraftResourceRef;\n },\n };\n\n if (!fromResourceById) {\n return Object.assign(resourceByGroup.asReadonly(), resourcesHandler);\n }\n\n effect(() => {\n const fromResourceByIdValue = fromResourceById?.();\n if (!fromResourceByIdValue) {\n return;\n }\n const resourceByGroupValue = resourceByGroup();\n Object.entries(fromResourceByIdValue).forEach(([key, resource]) => {\n const currentParams = params(\n resource as CraftResourceRef<FromObjectState, FromObjectResourceParams>,\n );\n if (!currentParams) {\n return;\n }\n\n untracked(() => {\n const group = identifier(currentParams as any);\n const existingCraftResourceRef = resourceByGroupValue[group];\n if (existingCraftResourceRef) {\n return;\n }\n resourcesHandler.addById(group, {\n paramsFromResourceById: resource as CraftResourceRef<\n FromObjectState,\n FromObjectResourceParams\n >,\n });\n });\n });\n });\n\n return Object.assign(resourceByGroup.asReadonly(), resourcesHandler);\n}\n\nconst RESOURCE_INSTANCE_TOKEN = new InjectionToken<\n CraftResourceRef<unknown, unknown>\n>(\n 'Injection token used to provide a dynamically created CraftResourceRef instance.',\n);\n\ninterface DynamicResourceConfig<T, R, GroupIdentifier extends string> {\n resourceOptions: ResourceOptions<T, R>;\n group: GroupIdentifier;\n}\n\n/**\n * It is not possible to instantiate a resource from within an effect directly:\n * NG0602: effect() cannot be called from within a reactive context.\n *\n * The workaround is to create a dynamic injection token using a factory function,\n * which instantiates the resource using the provided configuration.\n *\n * Maybe their is a better way to instantiate a resource dynamically.\n */\nfunction createDynamicResource<T, R, GroupIdentifier extends string>(\n parentInjector: Injector,\n resourceConfig: DynamicResourceConfig<T, R, GroupIdentifier>,\n) {\n const injector = Injector.create({\n providers: [\n {\n provide: RESOURCE_INSTANCE_TOKEN,\n useFactory: () => preservedResource(resourceConfig.resourceOptions),\n },\n ],\n parent: parentInjector,\n });\n\n const CraftResourceRef = injector.get(RESOURCE_INSTANCE_TOKEN);\n return CraftResourceRef as CraftResourceRef<T, R>;\n}\n","import { computed, resource, ResourceOptions, Signal } from '@angular/core';\nimport { CraftResourceRef } from './util/craft-resource-ref';\n\nexport function craftResource<Value, Params>(\n options: ResourceOptions<Value, Params>,\n): CraftResourceRef<Value, Params> {\n const resourceRef = resource(options);\n // do not use Object.assign, it will cause a cyclic dependency error\n return {\n value: resourceRef.value,\n hasValue: resourceRef.hasValue.bind(resourceRef),\n status: resourceRef.status,\n error: resourceRef.error,\n isLoading: resourceRef.isLoading,\n reload: resourceRef.reload.bind(resourceRef),\n destroy: resourceRef.destroy.bind(resourceRef),\n update: resourceRef.update.bind(resourceRef),\n set: resourceRef.set.bind(resourceRef),\n asReadonly: resourceRef.asReadonly.bind(resourceRef),\n safeValue: computed(\n () => (resourceRef.hasValue() ? resourceRef.value() : undefined),\n {\n debugName: 'craftResourceSafeValue',\n },\n ),\n paramSrc: options.params as Signal<Params>,\n state: computed(\n () => (resourceRef.hasValue() ? resourceRef.value() : undefined),\n {\n debugName: 'craftResourceState',\n },\n ),\n } as CraftResourceRef<Value, Params>;\n}\n","import {\n computed,\n isSignal,\n ResourceLoaderParams,\n ResourceOptions,\n ResourceStatus,\n ResourceStreamingLoader,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { InsertionsResourcesFactory } from './query.core';\nimport { ReadonlySource } from './util/source.type';\nimport { resourceById, ResourceByIdRef } from './resource-by-id';\nimport { isSource } from './util/util';\nimport { MergeObjects } from './util/util.type';\nimport { craftResource } from './craft-resource';\n\n// ! It looks like TS does not handle to expose the ResourceByIdHandler without erasing the () => ... part\nexport type AsyncProcessRef<\n Value,\n ArgParams,\n Params,\n Insertions,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n> = MergeObjects<\n [\n [unknown] extends [GroupIdentifier]\n ? {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n }\n : {},\n Insertions,\n IsMethod extends true\n ? {\n method: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n [unknown] extends [GroupIdentifier]\n ? {}\n : ResourceByIdRef<GroupIdentifier & string, Value, Params> & {\n _resourceById: ResourceByIdRef<\n GroupIdentifier & string,\n Value,\n Params\n >;\n /**\n * Get the associated resource by id\n *\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n *\n * return the associated resource or undefined if not existing\n */\n select: (id: GroupIdentifier) =>\n | {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n }\n | undefined;\n },\n ]\n>;\n\ntype AsyncProcessConfig<\n ResourceState,\n Params,\n ParamsArgs,\n SourceParams,\n GroupIdentifier,\n> = Omit<ResourceOptions<NoInfer<ResourceState>, Params>, 'params' | 'loader'> &\n (\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n preservePreviousValue?: () => boolean;\n }\n | {\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n preservePreviousValue?: () => boolean;\n }\n );\n\nexport type AsyncProcessOutput<\n State extends object | undefined,\n Params,\n ArgParams,\n SourceParams,\n GroupIdentifier,\n Insertions,\n> = AsyncProcessRef<\n State,\n ArgParams,\n Params,\n Insertions,\n [unknown] extends [ArgParams] ? false : true, // ! force to method to have one arg minimum, we can not compare SourceParams type, because it also infer Params\n SourceParams,\n GroupIdentifier\n>;\n\n/**\n * Creates an async method that manages asynchronous operations with automatic state tracking.\n *\n * This function creates a reactive async operation by:\n * - Managing loading, resolved, error, and idle states automatically\n * - Supporting both method-based (manual) and source-based (automatic) triggering\n * - Enabling parallel execution with identifiers\n * - Providing signals for value, status, error, and loading state\n * - Supporting streaming data with progressive updates\n * - Enabling custom insertions for extending functionality\n *\n * @remarks\n * **Trigger Patterns:**\n * - **Method-based**: Explicit `method` function returns params, called manually\n * - **Source-based**: Bound to a source using `afterRecomputation()`, triggers automatically\n *\n * **Use Cases:**\n * - **Debounced operations**: Search, validation with delay\n * - **Background tasks**: Processing without blocking UI\n * - **Polling**: Periodic data updates\n *\n * **State Management:**\n * - `idle`: Initial state, no operation started\n * - `loading`: Operation in progress\n * - `resolved`: Operation completed successfully\n * - `error`: Operation failed\n *\n * **Identifier Usage:**\n * - Without identifier: Single global state for the async method\n * - With identifier: Multiple parallel instances with independent states\n *\n * **Insertions:**\n * - Extend functionality with custom insertions\n * - Examples: persistence, caching, retry logic\n * - Insertions receive access to resource state and params\n *\n * @template AsyncProcesstate - The type of data returned by the async operation\n * @template AsyncProcessParams - The type of params passed to the loader\n * @template AsyncProcessArgsParams - The type of arguments for the method function\n * @template SourceParams - The type emitted by the source (for source-based methods)\n * @template GroupIdentifier - The type of identifier for parallel execution\n *\n * @param AsyncProcessConfig - Configuration object:\n * - `method`: Function returning params OR source for automatic triggering\n * - `loader`: Async function that performs the operation (mutually exclusive with `stream`)\n * - `stream`: Streaming loader for progressive updates (mutually exclusive with `loader`)\n * - `identifier`: Optional function to derive unique ID for parallel execution\n *\n * @returns An async method reference with:\n * - `value`: Signal containing the result (or undefined)\n * - `status`: Signal with current state ('idle' | 'loading' | 'resolved' | 'error')\n * - `error`: Signal containing error (or undefined)\n * - `isLoading`: Signal for loading state\n * - `hasValue()`: Function to check if value exists\n * - `method`: (method-based only) Function to trigger the operation\n * - `source`: (source-based only) Readonly source for automatic triggering\n * - `select(id)`: (with identifier) Access individual instance by ID\n *\n * @example\n * Basic method-based async method\n * ```ts\n * const delay = asyncProcess({\n * method: (delay: number) => delay,\n * loader: async ({ params }) => {\n * await new Promise(resolve => setTimeout(resolve, 500)); // Simulate delay\n * return 'done';\n * },\n * });\n *\n * // Trigger manually\n * delay.method(500);\n *\n * // Track state\n * console.log(delay.status()); // 'loading'\n * console.log(delay.isLoading()); // true\n *\n * // After completion\n * console.log(delay.status()); // 'resolved'\n * console.log(delay.value()); // 'done'\n * console.log(delay.hasValue()); // true\n * ```\n *\n * @example\n * Source-based async method for automatic execution\n * ```ts\n * const delaySource = source<number>();\n *\n * const delay = asyncProcess({\n * method: afterRecomputation(delaySource, (term) => term),\n * loader: async ({ params }) => {\n * // Debounce at source level\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done';\n * },\n * });\n *\n * // Triggers automatically when source emits\n * delaySource.set(500);\n * // -> delay executes automatically\n *\n * // No manual method, only source\n * console.log(delay.source); // ReadonlySource<number>\n * console.log(delay.status()); // Current state\n * ```\n *\n * @example\n * Async method with identifier for parallel operations\n * ```ts\n * const delayById = asyncProcess({\n * method: (id: string) => id,\n * identifier: (id) => id,\n * loader: async () => {\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done'; // Simulate delay\n * },\n * });\n *\n * delayById.method('id1');\n * delayById.method('id2');\n * delayById.method('id3');\n *\n * // Access individual states\n * const delay1 = delayById.select('id1');\n * console.log(delay1?.status()); // 'loading' or 'resolved'\n * console.log(delay1?.value()); // 'done'\n *\n * const delay2 = delayById.select('id2');\n * console.log(delay2?.status()); // Independent state\n * ```\n *\n * @example\n * Calling async js native API\n * ```ts\n * const shareContent = asyncProcess({\n * method: (payload: { title: string, url: string }) => payload,\n * loader: async ({ params }) => {\n * return navigator.share(params);\n * },\n * }, ({resource}) => ({isMenuOpen: computed(() => resource.status() === 'loading')} ));\n *\n * // Trigger shareContent\n * shareContent.method({ title: 'Hello AI!', url: 'https://example.com' });\n * shareContent.isMenuOpen(); // true while loading\n *\n * ```\n */\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >,\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\nexport function asyncProcess<\n AsyncProcesstate extends object | undefined,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n>(\n AsyncProcessConfig: AsyncProcessConfig<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier\n >,\n ...insertions: any[]\n): AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n> {\n const AsyncProcessResourceParamsFnSignal = signal<\n AsyncProcessParams | undefined\n >(undefined);\n\n const isConnectedToSource = isSource(AsyncProcessConfig.method);\n\n const isUsingIdentifier = 'identifier' in AsyncProcessConfig;\n\n const resourceParamsSrc = isConnectedToSource\n ? AsyncProcessConfig.method\n : AsyncProcessResourceParamsFnSignal;\n\n const resourceTarget = isUsingIdentifier\n ? resourceById<\n AsyncProcesstate,\n AsyncProcessParams,\n GroupIdentifier & string,\n string,\n unknown,\n unknown\n >({\n ...AsyncProcessConfig,\n params: resourceParamsSrc,\n identifier: AsyncProcessConfig.identifier,\n } as any)\n : craftResource<AsyncProcesstate, AsyncProcessParams>({\n ...AsyncProcessConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>);\n\n return Object.assign(\n resourceTarget,\n // byId is used to helps TS to correctly infer the resourceByGroup\n isUsingIdentifier\n ? {\n /**\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n */\n _resourceById: resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n AsyncProcesstate,\n AsyncProcessParams\n >,\n select: (id: GroupIdentifier) => {\n return computed(() => {\n const list = (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n AsyncProcesstate,\n AsyncProcessParams\n >\n )();\n //@ts-expect-error GroupIdentifier & string is not recognized correctly\n return list[id];\n })();\n },\n }\n : {},\n {\n method: isSignal(AsyncProcessConfig.method)\n ? undefined\n : (arg: AsyncProcessArgsParams) => {\n const result = AsyncProcessConfig.method(arg);\n if (isUsingIdentifier) {\n const id = AsyncProcessConfig.identifier?.(arg as any);\n (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n AsyncProcesstate,\n AsyncProcessParams\n >\n ).addById(id as GroupIdentifier & string);\n }\n AsyncProcessResourceParamsFnSignal.set(\n result as AsyncProcessParams,\n );\n return result;\n },\n },\n (\n insertions as InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<AsyncProcesstate>,\n NoInfer<AsyncProcessParams>,\n {}\n >[]\n )?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n ...(isUsingIdentifier\n ? { resourceById: resourceTarget }\n : { resource: resourceTarget }),\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n NoInfer<AsyncProcessParams>\n >,\n insertions: acc as {},\n state: resourceTarget.state,\n set: resourceTarget.set,\n update: resourceTarget.update,\n } as any),\n };\n },\n {} as Record<string, unknown>,\n ),\n ) as unknown as AsyncProcessOutput<\n AsyncProcesstate,\n AsyncProcessParams,\n AsyncProcessArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n >;\n}\n","import { linkedSignal, Signal, ValueEqualityFn } from '@angular/core';\nimport { ReadonlySource } from './util/source.type';\nimport { SignalSource } from './signal-source';\nimport { SourceBranded } from './util/util';\n\n/**\n * Creates a derived readonly source that transforms values from an origin source using a computation function.\n *\n * This function enables reactive transformations of source emissions by:\n * - Computing new values whenever the origin source emits\n * - Maintaining source semantics (emits only when explicitly set, not on first read)\n * - Supporting custom equality comparisons for memoization\n * - Providing both standard and value-preserving listeners\n * - Creating composable source pipelines\n *\n * @remarks\n * **Emission Behavior:**\n * - Only emits when the origin source emits (explicit set/update)\n * - First read returns `undefined` by default (maintains source semantics)\n * - Use `preserveLastValue` variant to get computed value on first read\n *\n * **Use Cases:**\n * - **Data transformation**: Convert source payloads to different shapes\n * - **Filtering**: Extract specific fields from complex source data\n * - **Formatting**: Apply formatting logic to source values\n * - **Type narrowing**: Cast or validate source data types\n * - **Composition**: Chain multiple source transformations\n * - **Business logic**: Apply domain-specific computations\n *\n * **Source vs Signal:**\n * - Sources emit only on explicit events (set/update calls)\n * - Signals recompute on every access when dependencies change\n * - computedSource maintains source lazy behavior\n *\n * **Equality Comparison:**\n * - Default: Uses Angular's default equality check\n * - Custom: Provide `equal` option for custom comparison\n * - Prevents unnecessary emissions when computed value hasn't changed\n *\n * @template SourceState - The type of values emitted by the origin source\n * @template ComputedValue - The type of values produced by the computation\n *\n * @param signalOrigin - The source or readonly source to derive from.\n * Values emitted by this source are passed to the computation function.\n *\n * @param computedFn - Function that transforms source values to computed values.\n * Called each time the origin source emits.\n *\n * @param options - Optional configuration:\n * - `equal`: Custom equality function for computed values\n * - `debugName`: Name for debugging purposes\n *\n * @returns A readonly source that emits computed values with:\n * - Standard behavior: First read returns `undefined`, subsequent reads return computed value after source emits\n * - `preserveLastValue` property: Returns computed value immediately on first read if source has emitted\n *\n * @example\n * Basic transformation of source data\n * ```ts\n * const userSource = source<{ firstName: string; lastName: string }>();\n *\n * // Compute full name from user data\n * const fullNameSource = computedSource(\n * userSource,\n * (user) => `${user.firstName} ${user.lastName}`\n * );\n *\n * // Use in async method or query\n * const greetUser = asyncProcess({\n * method: afterRecomputation(fullNameSource, (fullName) => fullName),\n * loader: async ({ params }) => {\n * return `Hello, ${params}!`;\n * },\n * });\n *\n * // Trigger chain\n * userSource.set({ firstName: 'John', lastName: 'Doe' });\n * // -> fullNameSource emits 'John Doe'\n * // -> greetUser executes with 'John Doe'\n * ```\n *\n * @example\n * Extracting specific fields from complex data\n * ```ts\n * type FormData = {\n * personal: { name: string; email: string };\n * address: { street: string; city: string };\n * preferences: { newsletter: boolean };\n * };\n *\n * const formSource = source<FormData>();\n *\n * // Extract only email for validation\n * const emailSource = computedSource(\n * formSource,\n * (form) => form.personal.email\n * );\n *\n * // Extract only address for geocoding\n * const addressSource = computedSource(\n * formSource,\n * (form) => form.address\n * );\n *\n * // Use extracted sources\n * const validateEmail = asyncProcess({\n * method: afterRecomputation(emailSource, (email) => email),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/validate-email', {\n * method: 'POST',\n * body: JSON.stringify({ email: params }),\n * });\n * return response.json();\n * },\n * });\n *\n * // Update form triggers both validations\n * formSource.set({\n * personal: { name: 'John', email: 'john@example.com' },\n * address: { street: '123 Main St', city: 'NYC' },\n * preferences: { newsletter: true },\n * });\n * ```\n *\n * @example\n * Chaining computed sources for multi-step transformation\n * ```ts\n * const inputSource = source<string>();\n *\n * // Step 1: Trim and lowercase\n * const normalizedSource = computedSource(\n * inputSource,\n * (input) => input.trim().toLowerCase()\n * );\n *\n * // Step 2: Extract search terms\n * const searchTermsSource = computedSource(\n * normalizedSource,\n * (normalized) => normalized.split(' ').filter(term => term.length > 0)\n * );\n *\n * // Step 3: Create search query\n * const searchQuerySource = computedSource(\n * searchTermsSource,\n * (terms) => ({ terms, operator: 'AND' as const })\n * );\n *\n * // Final async method uses fully transformed data\n * const search = asyncProcess({\n * method: afterRecomputation(searchQuerySource, (query) => query),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/search', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * // Single input triggers entire chain\n * inputSource.set(' Angular Signals ');\n * // -> normalizedSource emits 'angular signals'\n * // -> searchTermsSource emits ['angular', 'signals']\n * // -> searchQuerySource emits { terms: ['angular', 'signals'], operator: 'AND' }\n * // -> search executes\n * ```\n *\n * @example\n * Custom equality comparison\n * ```ts\n * type SearchParams = { query: string; timestamp: number };\n *\n * const searchSource = source<SearchParams>();\n *\n * // Only emit when query changes, ignore timestamp\n * const queryOnlySource = computedSource(\n * searchSource,\n * (params) => params.query,\n * {\n * equal: (a, b) => a === b, // Compare strings\n * }\n * );\n *\n * // Update with same query but different timestamp\n * searchSource.set({ query: 'test', timestamp: Date.now() });\n * // -> queryOnlySource emits 'test'\n *\n * searchSource.set({ query: 'test', timestamp: Date.now() });\n * // -> queryOnlySource does NOT emit (same query)\n *\n * searchSource.set({ query: 'new', timestamp: Date.now() });\n * // -> queryOnlySource emits 'new'\n * ```\n *\n * @example\n * Type narrowing and validation\n * ```ts\n * type ApiResponse =\n * | { type: 'success'; data: unknown }\n * | { type: 'error'; message: string };\n *\n * const responseSource = source<ApiResponse>();\n *\n * // Extract only successful data\n * const successDataSource = computedSource(\n * responseSource,\n * (response) => {\n * if (response.type === 'success') {\n * return response.data;\n * }\n * return null;\n * }\n * );\n *\n * // Extract only errors\n * const errorSource = computedSource(\n * responseSource,\n * (response) => {\n * if (response.type === 'error') {\n * return response.message;\n * }\n * return null;\n * }\n * );\n *\n * // Handle success and errors separately\n * const Processuccess = asyncProcess({\n * method: afterRecomputation(successDataSource, (data) => data),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * // Process successful data\n * return processData(params);\n * },\n * });\n *\n * const logError = asyncProcess({\n * method: afterRecomputation(errorSource, (error) => error),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * // Log error\n * await logToService(params);\n * return { logged: true };\n * },\n * });\n * ```\n *\n * @example\n * Formatting and presentation logic\n * ```ts\n * type Price = { amount: number; currency: string };\n *\n * const priceSource = source<Price>();\n *\n * // Format price for display\n * const formattedPriceSource = computedSource(\n * priceSource,\n * (price) => {\n * const formatter = new Intl.NumberFormat('en-US', {\n * style: 'currency',\n * currency: price.currency,\n * });\n * return formatter.format(price.amount);\n * }\n * );\n *\n * // Use formatted value in UI updates\n * const updatePriceDisplay = asyncProcess({\n * method: afterRecomputation(formattedPriceSource, (formatted) => formatted),\n * loader: async ({ params }) => {\n * // Update analytics or external service\n * await trackPriceView(params);\n * return { displayed: params };\n * },\n * });\n *\n * priceSource.set({ amount: 1234.56, currency: 'USD' });\n * // -> formattedPriceSource emits '$1,234.56'\n * ```\n *\n * @example\n * Using preserveLastValue for immediate computed access\n * ```ts\n * const counterSource = source<number>();\n *\n * const doubledSource = computedSource(\n * counterSource,\n * (count) => count * 2\n * );\n *\n * // Standard behavior\n * console.log(doubledSource()); // undefined (no emission yet)\n *\n * counterSource.set(5);\n * console.log(doubledSource()); // 10\n *\n * // Using preserveLastValue\n * const immediateDoubled = doubledSource.preserveLastValue;\n * console.log(immediateDoubled()); // 10 (gets last computed value immediately)\n * ```\n */\nexport function computedSource<SourceState, ComputedValue>(\n signalOrigin: SignalSource<SourceState> | ReadonlySource<SourceState>,\n computedFn: (sourceValue: NoInfer<SourceState>) => ComputedValue,\n options?: {\n equal?: ValueEqualityFn<NoInfer<ComputedValue> | undefined>;\n debugName?: string;\n },\n): ReadonlySource<ComputedValue> {\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<SourceState, ComputedValue | undefined>({\n source: signalOrigin as Signal<SourceState>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n\n return computedFn(currentSourceState);\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n },\n SourceBranded,\n ) as ReadonlySource<any>;\n}\n","// signal-proxy.ts\n// Purpose: Signal proxy that exposes read signals per property + write helpers for the underlying source signal.\n\nimport { Signal, signal, computed, isSignal } from '@angular/core';\nimport { MergeObject } from './util/types/util.type';\n\ntype AnyRecord = Record<PropertyKey, unknown>;\n\nexport type SignalWrapperParams<T extends object> = {\n readonly [K in keyof T]: T[K] extends Signal<infer U>\n ? Signal<U>\n : Signal<T[K]>;\n};\n\nexport type SignalProxy<\n T extends object,\n Public extends boolean = false\n> = MergeObject<\n {\n // For each property, you read it as a Signal of its final value (signals unwrapped).\n readonly [K in keyof T]: T[K] extends Signal<infer U>\n ? Signal<U>\n : Signal<T[K]>;\n },\n Public extends true\n ? {\n /** Readonly access to the whole object as a Signal<T> */\n readonly $raw: Signal<T>;\n\n /** Replace the whole object */\n $set(next: SignalWrapperParams<T>): void;\n\n /** Update the object with partial values */\n $patch(partial: Partial<SignalWrapperParams<T>>): void;\n\n /** Get the raw property (Signal or plain value) from the current object */\n $ref<K extends keyof T>(key: K): T[K];\n }\n : {}\n>;\n\nexport function createSignalProxy<T extends AnyRecord>(\n src: T | Signal<T>\n): SignalProxy<T, true> {\n const state: Signal<T> = isSignal(src) ? src : signal(src as T);\n\n // Cache property computed signals for referential stability\n const cache = new Map<PropertyKey, Signal<unknown>>();\n\n const api = {\n $raw: state,\n $set(next: T) {\n // Replace whole object\n if ((state as any).set) {\n (state as any).set(next);\n } else {\n (state as any)(next);\n }\n },\n $patch(partial: Partial<T>) {\n // Merge partial with current state\n const current = state();\n const updated = { ...current, ...partial };\n if ((state as any).set) {\n (state as any).set(updated);\n } else {\n (state as any)(updated);\n }\n },\n $ref<K extends keyof T>(key: K): T[K] {\n return (state() as any)[key];\n },\n };\n\n const handler: ProxyHandler<object> = {\n get(_target, prop: PropertyKey) {\n // Expose write API and $raw directly\n if (prop in api) return (api as any)[prop];\n\n if (\n prop === 'toJSON' ||\n prop === 'valueOf' ||\n prop === Symbol.toStringTag\n ) {\n return (state() as any)[prop];\n }\n\n if (cache.has(prop)) return cache.get(prop);\n\n // Computed read signal for property, unwrapping nested signals\n const s = computed(() => {\n const current = (state() as any)[prop];\n return isSignal(current) ? current() : current;\n });\n\n cache.set(prop, s);\n return s;\n },\n\n ownKeys() {\n return Reflect.ownKeys(state() as object);\n },\n has(_t, prop) {\n return prop in api || prop in (state() as object);\n },\n\n getOwnPropertyDescriptor(_t, prop) {\n if (prop in api) {\n return {\n configurable: true,\n enumerable: false,\n writable: false,\n value: (api as any)[prop],\n };\n }\n return {\n configurable: true,\n enumerable: true,\n writable: false,\n value: (this as any).get?.({}, prop),\n };\n },\n };\n\n return new Proxy({}, handler) as SignalProxy<T, true>;\n}\n","import { Prettify } from './util/util.type';\nimport {\n MergeObject,\n MergeObjects,\n UnionToTuple,\n} from './util/types/util.type';\nimport {\n assertInInjectionContext,\n DestroyRef,\n effect,\n EventEmitter,\n inject,\n InjectionToken,\n Injector,\n isSignal,\n Provider,\n signal,\n untracked,\n} from '@angular/core';\nimport { createSignalProxy, SignalProxy } from './signal-proxy';\nimport {\n ExcludeCommonKeys,\n HasKeys,\n RemoveIndexSignature,\n ReplaceStoreConfigToken,\n ToConnectableMethodFromInject,\n} from './util/util.type';\n\n//todo craft inouts should not accepts other params\n// todo filter private fields and methods ?\n\n// ! when adding standalone outputs make sure to assign like this: const c = Object.assign(() => true, {a: 5}) (function first)\n\n// todo find a way to simplify that, props exposed everywhere, _props only in stores and __props only in current store ?\n// todo doc about cloudProxy (it store all standalones methods automatically)\nexport type ContextConstraints = {\n props: {};\n methods: Record<string, Function>; //? (editable in injectCraft/craftCraft)\n _inputs: {}; //? (editable in injectCraft/craftCraft)\n _injections: {};\n _queryParams: {};\n _sources: {}; //? (editable in injectCraft/craftCraft)\n _mutation: {};\n _query: {};\n _AsyncProcess: {};\n _cloudProxy: {}; // A proxy that is used to share data between the injectable context and standalone outputs functions, composed store merge this proxy values\n _dependencies: {}; // todo implements composition alias and implements it\n _error: {};\n};\n\n// ! do not expose it\ntype _EmptyContext = {\n props: {};\n methods: Record<string, Function>;\n _inputs: {};\n _queryParams: {};\n _sources: {};\n _injections: {};\n _AsyncProcess: {};\n _mutation: {};\n _query: {};\n _cloudProxy: {};\n _dependencies: {};\n _error: {};\n};\n\nexport const EmptyContext = {\n props: {},\n methods: {},\n _inputs: {},\n _queryParams: {},\n _sources: {},\n _injections: {},\n _AsyncProcess: {},\n _mutation: {},\n _query: {},\n _cloudProxy: {},\n _dependencies: {},\n _error: {},\n};\n\nexport type EmptyContext = typeof EmptyContext;\n\nexport function contract<Implement>() {\n return {} as Implement;\n}\n\ntype EmptyStandaloneContext = {};\n\nexport function partialContext(\n context: Partial<ContextConstraints>,\n): ContextConstraints {\n return {\n props: context.props ?? {},\n methods: context.methods ?? {},\n _inputs: context._inputs ?? {},\n _injections: context._injections ?? {},\n _queryParams: context._queryParams ?? {},\n _sources: context._sources ?? {},\n _AsyncProcess: context._AsyncProcess ?? {},\n _mutation: context._mutation ?? {},\n _query: context._query ?? {},\n _cloudProxy: context._cloudProxy ?? {},\n _dependencies: context._dependencies ?? {},\n _error: context._error ?? {},\n };\n}\n\nexport type PartialContext<Context extends Partial<ContextConstraints>> = {\n props: [unknown] extends Context['props'] ? {} : Context['props'];\n methods: [unknown] extends Context['methods'] ? {} : Context['methods'];\n _inputs: [unknown] extends Context['_inputs'] ? {} : Context['_inputs'];\n _injections: [unknown] extends Context['_injections']\n ? {}\n : Context['_injections'];\n _queryParams: [unknown] extends Context['_queryParams']\n ? {}\n : Context['_queryParams'];\n _sources: [unknown] extends Context['_sources'] ? {} : Context['_sources'];\n _AsyncProcess: [unknown] extends Context['_AsyncProcess']\n ? {}\n : Context['_AsyncProcess'];\n _mutation: [unknown] extends Context['_mutation'] ? {} : Context['_mutation'];\n _query: [unknown] extends Context['_query'] ? {} : Context['_query'];\n _cloudProxy: [unknown] extends Context['_cloudProxy']\n ? {}\n : Context['_cloudProxy'];\n _dependencies: [unknown] extends Context['_dependencies']\n ? {}\n : Context['_dependencies'];\n _error: [unknown] extends Context['_error'] ? {} : Context['_error'];\n};\n\nexport type CloudProxy<T> = T;\nexport type CloudProxySource = Record<string, unknown>;\n\nexport type CraftFactoryEntries<Context extends ContextConstraints> =\n Context['_inputs'] &\n Context['_injections'] &\n Context['_sources'] &\n Context['props'] &\n Context['_AsyncProcess'];\n\nexport const craftFactoryEntries = (contextData: {\n context: ContextConstraints;\n}) => ({\n ...contextData.context._inputs,\n ...contextData.context._injections,\n ...contextData.context._sources,\n ...contextData.context.props,\n ...contextData.context._AsyncProcess,\n ...contextData.context._mutation,\n});\n\nexport type ContextInput<Context extends ContextConstraints> = {\n context: Context;\n};\n\n/**\n * ! Do not use it to generate the output of utilities like (craftQuery, craftMutation, etc..),\n * ! the context is not correctly inferred (use CraftFactoryUtility instead)\n */\n//todo _cloud should extends stadalone outputs _cloud\nexport type CraftFactory<\n Context extends ContextConstraints[],\n StoreConfig,\n CraftActionOutputs extends ContextConstraints,\n StandaloneContextOutputs extends {},\n> = (\n cloudProxy: CloudProxy<MergeContexts<Context>['_cloudProxy']>,\n storeConfig: StoreConfig,\n) => (<HostStoreConfig extends StoreConfigConstraints>(\n contextData: ContextInput<MergeContexts<Context>>,\n injector: Injector,\n storeConfig: StoreConfig, // do not use HostStoreConfig\n cloudProxy: MergeContexts<Context>['_cloudProxy'],\n) => CraftActionOutputs) & {\n standaloneOutputs?: StandaloneContextOutputs;\n};\n\nexport type CraftFactoryUtility<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n CraftActionOutputs extends ContextConstraints,\n StandaloneOutputs extends {} = {},\n> = (\n cloudProxy: CloudProxySource,\n storeConfig: StoreConfig,\n) => (<HostStoreConfig extends StoreConfigConstraints>(\n contextData: ContextInput<Context>,\n injector: Injector,\n storeConfig: HostStoreConfig,\n cloudProxy: Context['_cloudProxy'],\n) => CraftActionOutputs) & {\n standaloneOutputs?: StandaloneOutputs;\n};\nexport const EXTERNALLY_PROVIDED = 'EXTERNALLY_PROVIDED' as const;\n\ntype EnableInputsToBeExternallyProvided<Inputs, Enable> = {\n [key in keyof Inputs]: Enable extends true\n ? Inputs[key] | typeof EXTERNALLY_PROVIDED\n : Inputs[key];\n};\n\ntype IsNotFeature<ProvidedIn extends ProvidedInOption> =\n ProvidedIn extends 'feature' ? false : true;\n\ntype IsScoped<ProvidedIn extends ProvidedInOption> = ProvidedIn extends 'scoped'\n ? true\n : false;\n\ntype ReplaceStandaloneStoreToken<\n StandaloneOutputs extends StandaloneOutputsConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = {\n [K in keyof StandaloneOutputs as ReplaceStoreConfigToken<\n K & string,\n StoreConfig\n >]: StandaloneOutputs[K];\n};\ntype InjectCraftOutput<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n MethodsConnected,\n> = {\n [key in `inject${Capitalize<StoreConfig['name']>}Craft`]: <\n Config extends MergeObjects<\n [\n HasInputs extends true\n ? {\n inputs: InputsToPlugin;\n }\n : {},\n HasMethods extends true\n ? {\n methods?: Prettify<MethodsConnected>;\n }\n : {},\n ]\n >,\n >(\n ...args: HasInputs extends true\n ? [pluggableConfig: Config]\n : [pluggableConfig?: Config]\n ) => Prettify<\n RemoveIndexSignature<\n Context['props'] &\n ExcludeCommonKeys<\n Context['methods'],\n 'methods' extends keyof Config ? Config['methods'] : {}\n >\n >\n >;\n};\n\ntype CraftCompositionOutput<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n StandaloneOutputs,\n MethodsToConnect,\n MethodsConnected extends MethodsToConnect = MethodsToConnect,\n> = {\n [key in `craft${Capitalize<StoreConfig['name']>}`]: <\n HostContext extends ContextConstraints,\n HostStoreConfig extends StoreConfigConstraints,\n Config extends MergeObjects<\n [\n HasInputs extends true\n ? {\n inputs: Partial<InputsToPlugin>;\n }\n : {},\n HasMethods extends true\n ? {\n methods?: MethodsConnected;\n }\n : {},\n ]\n >,\n >(\n pluggableConfig?: (\n configFactory: CraftFactoryEntries<HostContext>,\n ) => MergeObject<\n MergeObject<\n Config,\n Exclude<\n 'methods' extends keyof Config ? keyof Config['methods'] : never,\n keyof MethodsToConnect\n > extends infer NotKnownMethodsUnion\n ? [NotKnownMethodsUnion] extends [undefined]\n ? {}\n : {\n errorMethodMsg: `Error: You are trying to add methods that are not defined in the connected store (${StoreConfig['name']}): ${UnionToTuple<NotKnownMethodsUnion> &\n string}`;\n }\n : {}\n >,\n Exclude<\n 'inputs' extends keyof Config ? keyof Config['inputs'] : never,\n keyof InputsToPlugin\n > extends infer NotKnownInputsUnion\n ? [NotKnownInputsUnion] extends [undefined]\n ? {}\n : {\n errorInputsMsg: `Error: You are trying to add inputs that are not defined in the connected store (${StoreConfig['name']}): ${UnionToTuple<NotKnownInputsUnion> &\n string}`;\n }\n : {}\n >,\n ) => CraftFactoryUtility<\n HostContext,\n HostStoreConfig,\n {\n props: Context['props'];\n methods: ExcludeCommonKeys<\n Context['methods'],\n 'methods' extends keyof Config ? Config['methods'] : {}\n >;\n _inputs: ExcludeCommonKeys<\n Context['_inputs'],\n 'inputs' extends keyof Config ? Config['inputs'] : {}\n >;\n _queryParams: Context['_queryParams'];\n _sources: Context['_sources'];\n _injections: Context['_injections'];\n _AsyncProcess: Context['_AsyncProcess'];\n _mutation: Context['_mutation'];\n _query: Context['_query'];\n _cloudProxy: Context['_cloudProxy'];\n _dependencies: Context['_dependencies'] & {\n [key in StoreConfig['name']]: {\n storeConfig: StoreConfig;\n context: Context;\n };\n };\n _error: Context['_error'];\n },\n [StandaloneOutputs] extends [{}] ? StandaloneOutputs : {}\n >;\n};\n\ntype CraftToken<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = {\n [key in `${Capitalize<StoreConfig['name']>}Craft`]: InjectionToken<\n Prettify<RemoveIndexSignature<Context['props'] & Context['methods']>>\n >;\n};\n\ntype META_CONTEXT<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = {\n [k in `_${Uppercase<StoreConfig['name']>}_META_STORE_CONTEXT`]: {\n storeConfig: StoreConfig;\n context: Prettify<Context>;\n };\n};\n\n// ! Plugged methods are not exposed in the final store (at type level, at runtime they exists and they are not hiding)\ntype ToCraftOutputs<\n Context extends ContextConstraints[],\n StandaloneContextOutputs extends StandaloneOutputsConstraints[],\n StoreConfig extends StoreConfigConstraints,\n MergedContext extends ContextConstraints = MergeContexts<Context>,\n StandaloneOutputs = ReplaceStandaloneStoreToken<\n MergeStandaloneContexts<StandaloneContextOutputs>,\n StoreConfig\n >,\n InputsToPlugin = EnableInputsToBeExternallyProvided<\n MergedContext['_inputs'],\n IsNotFeature<StoreConfig['providedIn']>\n >,\n HasError = HasKeys<MergedContext['_error']>,\n HasInputs = keyof InputsToPlugin extends never ? false : true,\n MethodsToConnect = ToConnectableMethodFromInject<MergedContext['methods']>,\n HasMethods = keyof MethodsToConnect extends never ? false : true,\n HasContractToImplements = [unknown] extends [StoreConfig['implements']]\n ? false\n : true,\n RespectContract = HasContractToImplements extends false\n ? true\n : IsEqual<\n RemoveIndexSignature<MergedContext['props'] & MergedContext['methods']>,\n NonNullable<StoreConfig['implements']>\n >,\n> = (HasError extends false\n ? RespectContract extends true\n ? InjectCraftOutput<\n MergedContext,\n StoreConfig,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n MethodsToConnect\n > &\n CraftCompositionOutput<\n MergedContext,\n StoreConfig,\n HasInputs,\n InputsToPlugin,\n HasMethods,\n StandaloneOutputs,\n MethodsToConnect\n > &\n CraftToken<MergedContext, StoreConfig> &\n (IsScoped<StoreConfig['providedIn']> extends true\n ? {\n [k in `provide${Capitalize<StoreConfig['name']>}Craft`]: () => Provider;\n }\n : {}) &\n StandaloneOutputs\n : {\n error: NonNullable<StoreConfig['implements']> extends Function\n ? 'Contract Implementation Error: The current contract is not called properly. Did you forget to call it as a function? i.e., contract<...>()'\n : 'Contract Implementation Error: The current contract is not respected.';\n }\n : {\n error: MergedContext['_error'];\n }) &\n META_CONTEXT<MergedContext, StoreConfig>;\n\ntype IsEqual<A, B> =\n (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2\n ? (<T>() => T extends B ? 1 : 2) extends <T>() => T extends A ? 1 : 2\n ? true\n : false\n : false;\n\ntype Diff<A, B> = {\n added: Exclude<keyof B, keyof A>;\n removed: Exclude<keyof A, keyof B>;\n changed: ChangedKeys<A, B>;\n};\n\ntype ChangedKeys<A, B> = {\n [K in keyof A & keyof B]: A[K] extends B[K]\n ? B[K] extends A[K]\n ? never\n : K\n : K;\n}[keyof A & keyof B];\n\ntype ProvidedInOption = 'root' | 'scoped' | 'feature';\nexport type StoreConfigConstraints = {\n providedIn: ProvidedInOption;\n name: string;\n implements?: unknown;\n};\n\ntype MergeContexts<C extends ContextConstraints[]> = C extends [\n infer First,\n ...infer Rest,\n]\n ? First extends ContextConstraints\n ? Rest extends ContextConstraints[]\n ? MergeTwoContexts<First, MergeContexts<Rest>>\n : First\n : never\n : _EmptyContext;\n\ntype MergeStandaloneContexts<C extends StandaloneOutputsConstraints[]> =\n C extends [infer First, ...infer Rest]\n ? First extends StandaloneOutputsConstraints\n ? Rest extends StandaloneOutputsConstraints[]\n ? First & MergeStandaloneContexts<Rest>\n : First\n : never\n : _EmptyContext;\n\nexport type MergeTwoContexts<\n A extends ContextConstraints,\n B extends ContextConstraints,\n> = {\n methods: A['methods'] & B['methods'];\n props: A['props'] & B['props'];\n _inputs: A['_inputs'] & B['_inputs'];\n _injections: A['_injections'] & B['_injections'];\n _mutation: A['_mutation'] & B['_mutation'];\n _query: A['_query'] & B['_query'];\n _queryParams: A['_queryParams'] & B['_queryParams'];\n _sources: A['_sources'] & B['_sources'];\n _AsyncProcess: A['_AsyncProcess'] & B['_AsyncProcess'];\n _cloudProxy: A['_cloudProxy'] & B['_cloudProxy'];\n _dependencies: A['_dependencies'] & B['_dependencies'];\n _error: A['_error'] & B['_error'];\n};\n\ntype StandaloneOutputsConstraints = {};\n\n/**\n * Creates a type-safe, composable state management store with Angular dependency injection.\n *\n * This is the core function for building craft stores. It enables:\n * - **Type-safe composition**: Chain multiple craft utilities (craftState, craftQuery, craftMutation, etc.)\n * - **Dependency injection**: Choose between root-level or feature-level provision\n * - **Smart naming**: Auto-generates injection and composition functions based on store name\n * - **Store composition**: Connect stores together via craftX functions with input/method binding\n * - **Standalone methods**: Export methods that can be called outside injection context\n * - **Contract enforcement**: Optional type contracts for store implementation\n * - **Error detection**: Type-level errors for configuration mistakes\n *\n * @remarks\n * **Naming Convention:**\n * Based on the `options.name` parameter, craft automatically generates:\n * - **Injection function**: `inject{Name}Craft()` - Injects the store instance\n * - **Composition function**: `craft{Name}(config?)` - Composes this store into another\n * - **Injection token**: `{Name}Craft` - Angular injection token for the store\n * - **Metadata**: `_{UPPERCASE_NAME}_META_STORE_CONTEXT` - Type metadata for the store\n *\n * Examples:\n * - `name: 'counter'` → `injectCounterCraft()`, `craftCounter()`\n * - `name: 'userAuth'` → `injectUserAuthCraft()`, `craftUserAuth()`\n * - `name: 'dataPagination'` → `injectDataPaginationCraft()`, `craftDataPagination()`\n *\n * **ProvidedIn Strategy:**\n * The `providedIn` option controls how Angular provides the store:\n *\n * - **`'root'`** (Global singleton):\n * - Single instance shared across the entire application\n * - Survives route changes and component destruction\n * - Ideal for: global state, authentication, app configuration\n * - When composed into other stores, the same instance is reused\n *\n * - **`'feature'`** (Scoped instances):\n * - New instance created per injection context\n * - Does not survive outside its injection scope\n * - Ideal for: component-specific state, route-scoped data, isolated features\n * - When composed into other stores, each host gets its own instance\n *\n * **Store Composition:**\n * Use the generated `craft{Name}()` function to compose one store into another:\n * - Access another store's state, methods, and capabilities\n * - Bind inputs from host store to composed store\n * - Connect host methods to composed store sources\n * - Unbound inputs/methods are automatically propagated to the host\n * - Type-safe with error detection for invalid bindings\n *\n * **Injection with Input/Method Binding:**\n * The `inject{Name}Craft()` function accepts a configuration object to:\n * - **Bind inputs**: Pass signals or values to store inputs\n * - **Connect methods to sources**: Replace methods with source emissions\n * - Enable dynamic configuration at injection time\n * - Reduce boilerplate when the store is used\n *\n * **Error Detection:**\n * The type system provides compile-time errors for:\n * - **`errorMethodMsg`**: When connecting methods that don't exist in the composed store\n * - **`errorInputsMsg`**: When binding inputs that aren't defined in the composed store\n * - **Contract violations**: When the store doesn't satisfy its `implements` contract\n * - These errors appear as properties on the configuration object with descriptive messages\n *\n * **Standalone Methods:**\n * Craft utilities (craftSources, craftMutations, etc.) can expose standalone methods:\n * - These are returned directly from `craft()` and can be destructured\n * - Can be called outside Angular's injection context\n * - Useful for event handlers, callbacks, external integrations\n * - Examples: `setReset()`, `setPaginationQueryParams()`\n *\n * @template Context - The craft store context type containing all store capabilities\n * @template StoreConfig - The store configuration type with name and providedIn\n * @template ProvidedIn - The Angular injection scope ('root' or 'feature')\n * @template Name - The store name used for generating function names\n * @template ToImplementContract - Optional contract type the store must satisfy\n *\n * @param options - Store configuration object\n * @param options.name - Store name (camelCase recommended). Used to generate function names.\n * @param options.providedIn - Angular injection scope. 'root' for global singleton, 'feature' for scoped instances.\n * @param options.implements - Optional contract type. Use `contract<YourType>()` to enforce implementation.\n * @param factories - Variable number of craft utility functions (craftState, craftQuery, craftSources, etc.)\n * Each factory receives the accumulated context from previous factories.\n *\n * @returns An object containing:\n * - **`inject{Name}Craft`**: Function to inject the store with optional input/method binding\n * - **`craft{Name}`**: Function to compose this store into another store\n * - **`{Name}Craft`**: Angular injection token for manual injection\n * - **`_{UPPERCASE_NAME}_META_STORE_CONTEXT`**: Type metadata (for advanced use cases)\n * - **Standalone methods**: Any standalone outputs from craft utilities (e.g., `setReset()`)\n *\n * @example\n * Basic counter store with sources and state\n * ```ts\n * const { injectCounterCraft, setIncrement, setDecrement, setReset } = craft(\n * { name: 'counter', providedIn: 'root' },\n * craftSources({\n * increment: source<void>(),\n * decrement: source<void>(),\n * reset: source<void>(),\n * }),\n * craftState('count', ({ increment, decrement, reset }) =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * increment: afterRecomputation(increment, () => set(state() + 1)),\n * decrement: afterRecomputation(decrement, () => set(state() - 1)),\n * reset: afterRecomputation(reset, () => set(0)),\n * })\n * )\n * )\n * );\n *\n * // In a component\n * const store = injectCounterCraft();\n * console.log(store.count()); // 0\n * store.setIncrement(); // count: 1\n * store.setDecrement(); // count: 0\n * store.setReset(); // count: 0\n *\n * // Standalone methods work outside injection context\n * document.addEventListener('click', () => {\n * setIncrement(); // Works!\n * });\n * ```\n *\n * @example\n * Store with inputs for dynamic configuration\n * ```ts\n * const { injectTimerCraft } = craft(\n * { name: 'timer', providedIn: 'feature' }, // Feature-scoped\n * craftInputs({\n * initialValue: undefined as number | undefined,\n * step: undefined as number | undefined,\n * }),\n * craftSources({\n * tick: source<void>(),\n * }),\n * craftState('time', ({ initialValue, step, tick }) =>\n * state(\n * linkedSignal(() => initialValue() ?? 0),\n * ({ state, set }) => ({\n * tick: afterRecomputation(tick, () => {\n * set(state() + (step() ?? 1));\n * }),\n * })\n * )\n * )\n * );\n *\n * // Inject with input binding\n * const timer1 = injectTimerCraft({\n * inputs: {\n * initialValue: signal(100),\n * step: signal(5),\n * },\n * });\n *\n * const timer2 = injectTimerCraft({\n * inputs: {\n * initialValue: signal(0),\n * step: signal(1),\n * },\n * });\n *\n * // Each instance is independent (feature-scoped)\n * timer1.time(); // 100\n * timer2.time(); // 0\n * ```\n *\n * @example\n * Store composition with root-level singleton\n * ```ts\n * // Global authentication store\n * const { craftAuth } = craft(\n * { name: 'auth', providedIn: 'root' }, // Global singleton\n * craftState('user', () =>\n * state(\n * { id: null, name: '' },\n * ({ set }) => ({\n * login: (user: { id: number; name: string }) => set(user),\n * logout: () => set({ id: null, name: '' }),\n * })\n * )\n * )\n * );\n *\n * // Dashboard store uses auth\n * const { injectDashboardCraft } = craft(\n * { name: 'dashboard', providedIn: 'root' },\n * craftAuth(), // No config needed, uses shared instance\n * craftState('dashboardData', ({ user }) =>\n * state(\n * linkedSignal(() => `Dashboard for ${user().name}`),\n * () => ({})\n * )\n * )\n * );\n *\n * // Profile store also uses auth\n * const { injectProfileCraft } = craft(\n * { name: 'profile', providedIn: 'root' },\n * craftAuth(), // Same auth instance\n * craftState('profileData', ({ user }) =>\n * state(\n * linkedSignal(() => `Profile: ${user().name}`),\n * () => ({})\n * )\n * )\n * );\n *\n * // Both stores share the same auth instance\n * const dashboard = injectDashboardCraft();\n * const profile = injectProfileCraft();\n *\n * dashboard.userLogin({ id: 1, name: 'Alice' });\n * console.log(dashboard.user().name); // 'Alice'\n * console.log(profile.user().name); // 'Alice' (same instance!)\n * ```\n *\n * @example\n * Store composition with feature-level scoping\n * ```ts\n * // Reusable pagination store\n * const { craftPagination } = craft(\n * { name: 'pagination', providedIn: 'feature' }, // Scoped instance\n * craftInputs({\n * pageSize: undefined as number | undefined,\n * }),\n * craftState('page', ({ pageSize }) =>\n * state(\n * { current: 1, size: linkedSignal(() => pageSize() ?? 10) },\n * ({ state, set }) => ({\n * nextPage: () => set({ ...state(), current: state().current + 1 }),\n * prevPage: () => set({ ...state(), current: state().current - 1 }),\n * })\n * )\n * )\n * );\n *\n * // Users table with pagination\n * const { injectUsersTableCraft } = craft(\n * { name: 'usersTable', providedIn: 'root' },\n * craftPagination(() => ({\n * inputs: { pageSize: signal(20) },\n * })),\n * craftState('users', () => state([], () => ({})))\n * );\n *\n * // Products table with pagination\n * const { injectProductsTableCraft } = craft(\n * { name: 'productsTable', providedIn: 'root' },\n * craftPagination(() => ({\n * inputs: { pageSize: signal(50) },\n * })),\n * craftState('products', () => state([], () => ({})))\n * );\n *\n * // Each table has its own pagination instance\n * const usersTable = injectUsersTableCraft();\n * const productsTable = injectProductsTableCraft();\n *\n * usersTable.page().size; // 20\n * productsTable.page().size; // 50\n * usersTable.pageNextPage();\n * usersTable.page().current; // 2\n * productsTable.page().current; // 1 (independent!)\n * ```\n *\n * @example\n * Binding methods to sources during composition\n *\n * When composing stores, you can connect methods from a composed store to sources\n * in the host store. When a method is connected to a source:\n * - The method is automatically called when the source emits a value\n * - **The connected method is NOT exposed in the final host store**\n * - Only the source's setter method (e.g., `emitSourceName`) remains accessible\n * - This prevents redundant API surface and enforces reactive patterns\n *\n * ```ts\n * const { craftLogger } = craft(\n * { name: 'logger', providedIn: 'root' },\n * craftSources(() => ({\n * log: source$<string>(),\n * })),\n * craftState('logs', ({ log }) =>\n * state(\n * [] as string[],\n * ({ state, set }) => ({\n * addLog: afterRecomputation(log, (message) => {\n * set([...state(), message]);\n * }),\n * clear: () => set([]),\n * })\n * )\n * )\n * );\n *\n * const { injectAppCraft } = craft(\n * { name: 'app', providedIn: 'root' },\n * craftSources(() => ({\n * appError: source$<string>(),\n * })),\n * craftState('errorCount', ({ appError }) =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * onError: afterRecomputation(appError, () => set(state() + 1)),\n * })\n * )\n * ),\n * // Connect appError source to logger's clear method\n * craftLogger(({ appError }) => ({\n * methods: {\n * logsClear: appError, // When appError emits, call logsClear\n * },\n * }))\n * );\n *\n * const app = injectAppCraft();\n * app.emitLog('User logged in');\n * app.logs().length; // 1\n *\n * // Note: app.logsClear is NOT available (connected to source)\n * // Only app.emitAppError is available\n * app.emitAppError('Something went wrong');\n * // -> errorCount incremented\n * // -> logs cleared (logsClear called automatically via appError source)\n * app.logs().length; // 0\n * app.errorCount(); // 1\n * ```\n *\n * @example\n * Connecting composed store methods to host sources with query params\n * ```ts\n * const { craftGenericQueryParams } = craft(\n * { name: 'GenericQueryParams', providedIn: 'root' },\n * craftQueryParams(() => ({\n * pagination: queryParam(\n * {\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * },\n * ({ set }) => ({\n * reset: () => set({ page: 1 }),\n * goTo: (page: number) => set({ page }),\n * }),\n * ),\n * })),\n * );\n *\n * const { injectHostCraft } = craft(\n * { name: 'host', providedIn: 'root' },\n * craftSources(() => ({\n * reset: source$<void>(),\n * goTo: source$<number>(),\n * })),\n * craftGenericQueryParams(({ reset, goTo }) => ({\n * methods: {\n * paginationReset: reset, // Connect to reset source\n * paginationGoTo: goTo, // Connect to goTo source\n * },\n * })),\n * );\n *\n * const host = injectHostCraft();\n *\n * // ❌ These methods are NOT exposed (connected to sources):\n * // host.paginationReset\n * // host.paginationGoTo\n *\n * // ✅ Only source emitters are available:\n * host.emitGoTo(5); // Triggers paginationGoTo(5)\n * host.pagination(); // { page: 5 }\n * host.emitReset(); // Triggers paginationReset()\n * host.pagination(); // { page: 1 }\n * ```\n *\n * @example\n * Input/method binding with EXTERNALLY_PROVIDED\n * ```ts\n * const { craftTheme } = craft(\n * { name: 'theme', providedIn: 'root' },\n * craftInputs({\n * initialTheme: undefined as 'light' | 'dark' | undefined,\n * }),\n * craftState('theme', ({ initialTheme }) =>\n * state(\n * linkedSignal(() => initialTheme() ?? 'light'),\n * ({ set }) => ({\n * setTheme: (theme: 'light' | 'dark') => set(theme),\n * })\n * )\n * )\n * );\n *\n * // Host store binds the input\n * const { injectAppCraft } = craft(\n * { name: 'app', providedIn: 'root' },\n * craftState('appTheme', () => state('dark' as 'light' | 'dark', () => ({}))),\n * craftTheme(({ appTheme }) => ({\n * inputs: {\n * initialTheme: appTheme, // Bind input\n * },\n * }))\n * );\n *\n * // Another host provides the input externally\n * const { craftOtherApp } = craft(\n * { name: 'otherApp', providedIn: 'root' },\n * // Input is not bound here, marked as EXTERNALLY_PROVIDED\n * craftTheme(() => ({\n * inputs: {\n * initialTheme: 'EXTERNALLY_PROVIDED',\n * },\n * }))\n * );\n *\n * // When composing otherApp, initialTheme must be provided\n * const { injectFinalCraft } = craft(\n * { name: 'final', providedIn: 'root' },\n * craftOtherApp(() => ({\n * inputs: {\n * initialTheme: signal('light'), // Must provide this\n * },\n * }))\n * );\n * ```\n *\n * @example\n * Query and mutation with automatic reactivity\n * ```ts\n * const { injectTodosCraft } = craft(\n * { name: 'todos', providedIn: 'root' },\n * craftQuery('todoList', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json();\n * },\n * })\n * ),\n * craftMutations(() => ({\n * addTodo: mutation({\n * method: (text: string) => ({ text }),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/todos', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * onSuccess: ({ helpers }) => {\n * // Invalidate query on success\n * helpers.invalidateQueries(['todoList']);\n * },\n * }),\n * }))\n * );\n *\n * const todos = injectTodosCraft();\n * todos.mutateAddTodo('Buy milk'); // Mutation\n * // -> todoList query auto-refreshes after mutation succeeds\n * ```\n *\n * @example\n * Query params for URL synchronization\n * ```ts\n * const { injectSearchCraft, setSearchQueryParams } = craft(\n * { name: 'search', providedIn: 'root' },\n * craftQueryParam('search', () =>\n * queryParam({\n * state: {\n * query: {\n * fallbackValue: '',\n * parse: (value) => value,\n * serialize: (value) => value,\n * },\n * page: {\n * fallbackValue: 1,\n * parse: (value) => parseInt(value, 10),\n * serialize: (value) => String(value),\n * },\n * },\n * })\n * ),\n * craftQuery('results', ({ searchQuery, searchPage }) =>\n * query({\n * params: linkedSignal(() => ({\n * q: searchQuery(),\n * page: searchPage(),\n * })),\n * loader: async ({ params }) => {\n * const response = await fetch(\n * `/api/search?q=${params.q}&page=${params.page}`\n * );\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const search = injectSearchCraft();\n *\n * // Change query params (syncs to URL)\n * setSearchQueryParams({ query: 'angular', page: 2 });\n * // -> URL updates to ?query=angular&page=2\n * // -> results query auto-refreshes with new params\n * ```\n *\n * @example\n * Async methods for side effects\n * ```ts\n * const { injectNotificationsCraft } = craft(\n * { name: 'notifications', providedIn: 'root' },\n * craftState('messages', () =>\n * state(\n * [] as string[],\n * ({ state, set }) => ({\n * addMessage: (msg: string) => set([...state(), msg]),\n * clear: () => set([]),\n * })\n * )\n * ),\n * craftAsyncProcesses(() => ({\n * showNotification: asyncProcess({\n * method: (message: string, duration: number) => ({ message, duration }),\n * loader: async ({ params, helpers }) => {\n * helpers.methods.messagesAddMessage(params.message);\n * await new Promise((resolve) => setTimeout(resolve, params.duration));\n * // Auto-remove after duration\n * const current = helpers.props.messages();\n * helpers.methods.messagesClear();\n * return 'done';\n * },\n * }),\n * }))\n * );\n *\n * const notifications = injectNotificationsCraft();\n * notifications.showNotificationExecute('Hello!', 3000);\n * // Message appears, then disappears after 3 seconds\n * ```\n *\n * @example\n * Contract enforcement for type safety\n * ```ts\n * type CounterContract = {\n * count: Signal<number>;\n * increment: () => void;\n * decrement: () => void;\n * };\n *\n * // This store satisfies the contract\n * const { injectCounterCraft } = craft(\n * {\n * name: 'counter',\n * providedIn: 'root',\n * implements: contract<CounterContract>(),\n * },\n * craftState('count', () =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * increment: () => set(state() + 1),\n * decrement: () => set(state() - 1),\n * })\n * )\n * )\n * );\n *\n * // This would cause a type error (missing decrement)\n * const { injectBadCounterCraft } = craft(\n * {\n * name: 'badCounter',\n * providedIn: 'root',\n * implements: contract<CounterContract>(), // Error!\n * },\n * craftState('count', () =>\n * state(\n * 0,\n * ({ state, set }) => ({\n * increment: () => set(state() + 1),\n * // Missing decrement!\n * })\n * )\n * )\n * );\n * ```\n *\n * @example\n * Error detection for invalid composition\n * ```ts\n * const { craftLogger } = craft(\n * { name: 'logger', providedIn: 'root' },\n * craftState('logs', () =>\n * state(\n * [] as string[],\n * ({ set }) => ({\n * clear: () => set([]),\n * })\n * )\n * )\n * );\n *\n * const { injectAppCraft } = craft(\n * { name: 'app', providedIn: 'root' },\n * craftLogger(() => ({\n * methods: {\n * logsClear: signal<void>(), // OK\n * logsInvalidMethod: signal<void>(), // Type error!\n * // errorMethodMsg: \"Error: You are trying to add methods that are not\n * // defined in the connected store (logger): logsInvalidMethod\"\n * },\n * inputs: {\n * nonExistentInput: signal(5), // Type error!\n * // errorInputsMsg: \"Error: You are trying to add inputs that are not\n * // defined in the connected store (logger): nonExistentInput\"\n * },\n * }))\n * );\n * ```\n *\n * @example\n * Complex multi-store composition\n * ```ts\n * // Shared auth store\n * const { craftAuth } = craft(\n * { name: 'auth', providedIn: 'root' },\n * craftState('user', () =>\n * state({ id: null, role: 'guest' }, ({ set }) => ({\n * login: (user: { id: number; role: string }) => set(user),\n * logout: () => set({ id: null, role: 'guest' }),\n * }))\n * )\n * );\n *\n * // Pagination feature\n * const { craftPagination } = craft(\n * { name: 'pagination', providedIn: 'feature' },\n * craftInputs({ pageSize: undefined as number | undefined }),\n * craftState('page', ({ pageSize }) =>\n * state({ current: 1, size: pageSize() ?? 10 }, ({ state, set }) => ({\n * next: () => set({ ...state(), current: state().current + 1 }),\n * prev: () => set({ ...state(), current: state().current - 1 }),\n * }))\n * )\n * );\n *\n * // Admin panel combines both\n * const { injectAdminPanelCraft } = craft(\n * { name: 'adminPanel', providedIn: 'root' },\n * craftAuth(), // Shared auth\n * craftPagination(({ user }) => ({\n * // Feature pagination with dynamic pageSize based on role\n * inputs: {\n * pageSize: linkedSignal(() => (user().role === 'admin' ? 100 : 20)),\n * },\n * })),\n * craftQuery('adminData', ({ user, page }) =>\n * query({\n * params: linkedSignal(() => ({\n * userId: user().id,\n * page: page().current,\n * })),\n * loader: async ({ params }) => {\n * // Fetch data...\n * },\n * })\n * )\n * );\n *\n * const admin = injectAdminPanelCraft();\n * admin.userLogin({ id: 1, role: 'admin' });\n * admin.page().size; // 100 (admin gets larger page size)\n * admin.pageNext();\n * // -> adminData query refreshes automatically\n * ```\n */\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n outputs8 extends ContextConstraints,\n outputs9 extends ContextConstraints,\n outputs10 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n standaloneOutputs8 extends StandaloneOutputsConstraints,\n standaloneOutputs9 extends StandaloneOutputsConstraints,\n standaloneOutputs10 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n factory8: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs8,\n standaloneOutputs8\n >,\n factory9: CraftFactory<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs9,\n standaloneOutputs9\n >,\n factory10: CraftFactory<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n outputs9,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs10,\n standaloneOutputs10\n >,\n): ToCraftOutputs<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n outputs9,\n outputs10,\n ],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n standaloneOutputs8,\n standaloneOutputs9,\n standaloneOutputs10,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n outputs8 extends ContextConstraints,\n outputs9 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n standaloneOutputs8 extends StandaloneOutputsConstraints,\n standaloneOutputs9 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n factory8: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs8,\n standaloneOutputs8\n >,\n factory9: CraftFactory<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs9,\n standaloneOutputs9\n >,\n): ToCraftOutputs<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n outputs9,\n ],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n standaloneOutputs8,\n standaloneOutputs9,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n outputs8 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n standaloneOutputs8 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n factory8: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs8,\n standaloneOutputs8\n >,\n): ToCraftOutputs<\n [\n outputs1,\n outputs2,\n outputs3,\n outputs4,\n outputs5,\n outputs6,\n outputs7,\n outputs8,\n ],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n standaloneOutputs8,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n outputs7 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n standaloneOutputs7 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n factory7: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs7,\n standaloneOutputs7\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6, outputs7],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n standaloneOutputs7,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n outputs6 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n standaloneOutputs6 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n factory6: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs6,\n standaloneOutputs6\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4, outputs5, outputs6],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n standaloneOutputs6,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n outputs5 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n standaloneOutputs5 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n factory5: CraftFactory<\n [outputs1, outputs2, outputs3, outputs4],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs5,\n standaloneOutputs5\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4, outputs5],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n standaloneOutputs5,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n outputs4 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n standaloneOutputs4 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n factory4: CraftFactory<\n [outputs1, outputs2, outputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs4,\n standaloneOutputs4\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3, outputs4],\n [\n standaloneOutputs1,\n standaloneOutputs2,\n standaloneOutputs3,\n standaloneOutputs4,\n ],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n outputs3 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n standaloneOutputs3 extends StandaloneOutputsConstraints,\n const Name extends string,\n const ProvidedIn extends ProvidedInOption,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n factory3: CraftFactory<\n [outputs1, outputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs3,\n standaloneOutputs3\n >,\n): ToCraftOutputs<\n [outputs1, outputs2, outputs3],\n [standaloneOutputs1, standaloneOutputs2, standaloneOutputs3],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n outputs2 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n standaloneOutputs2 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n factory2: CraftFactory<\n [outputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs2,\n standaloneOutputs2\n >,\n): ToCraftOutputs<\n [outputs1, outputs2],\n [standaloneOutputs1, standaloneOutputs2],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft<\n outputs1 extends ContextConstraints,\n standaloneOutputs1 extends StandaloneOutputsConstraints,\n const ProvidedIn extends ProvidedInOption,\n const Name extends string,\n ToImplementContract,\n>(\n options: {\n providedIn: ProvidedIn;\n name: Name;\n implements?: ToImplementContract;\n },\n factory1: CraftFactory<\n [_EmptyContext],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n },\n outputs1,\n standaloneOutputs1\n >,\n): ToCraftOutputs<\n [outputs1],\n [standaloneOutputs1],\n {\n providedIn: NoInfer<ProvidedIn>;\n name: NoInfer<Name>;\n implements?: ToImplementContract;\n }\n>;\nexport function craft(\n options: StoreConfigConstraints,\n ...factoriesList: CraftFactory<\n [_EmptyContext],\n {\n providedIn: ProvidedInOption;\n name: string;\n },\n ContextConstraints,\n {}\n >[]\n): ToCraftOutputs<\n _EmptyContext[],\n EmptyStandaloneContext[],\n {\n name: string;\n providedIn: ProvidedInOption;\n implements?: unknown;\n }\n> {\n const providedIn =\n options.providedIn && ['scoped', 'feature'].includes(options.providedIn)\n ? null\n : 'root';\n const storeConfig: StoreConfigConstraints = {\n providedIn: options?.providedIn,\n name: options?.name,\n implements: options?.implements,\n };\n const name = options?.name ?? '';\n const capitalizedName = name\n ? name.charAt(0).toUpperCase() + name.slice(1)\n : '';\n const injectNameCraft = `inject${capitalizedName}Craft`;\n const craftNameCraft = `craft${capitalizedName}`;\n\n const _cloudProxy = new Proxy({}, {});\n\n const extractedStandaloneOutputs = factoriesList.reduce(\n (acc, factoryWithStandalone, index) => {\n const r = factoryWithStandalone(_cloudProxy, storeConfig) ?? {};\n acc = {\n ...acc,\n ...r,\n };\n return acc;\n },\n {} as Record<string, unknown>,\n );\n\n // _cloudProxy will now have all the standalone outputs assigned to it\n Object.assign(_cloudProxy, extractedStandaloneOutputs);\n\n // used to share context, when providedIn is not root and also used with 'inject' and with 'using'\n let sharedContext: ContextConstraints | undefined = undefined;\n const pluggableInputs = createSignalProxy(signal({}));\n let inputsKeysSet: Set<string> | undefined = undefined;\n const craftFactory = () => {\n const injector = inject(Injector);\n const { propsAndMethods, context } = mergeContextAndProps({\n factoriesList,\n pluggableInputs,\n injector,\n storeConfig,\n _cloudProxy,\n });\n inputsKeysSet = new Set(\n Object.keys((context as ContextConstraints)._inputs),\n );\n sharedContext = context;\n\n return propsAndMethods;\n };\n const token = providedIn\n ? new InjectionToken(`Craft${capitalizedName}Token`, {\n providedIn,\n factory: craftFactory,\n })\n : new InjectionToken(`Craft${capitalizedName}Token`);\n const provideCraftFn = () =>\n ({\n provide: token,\n useFactory: craftFactory,\n }) satisfies Provider;\n\n const injectCraft = () => injectNameCraft;\n\n return {\n [injectNameCraft]: (entries?: {\n inputs?: Record<string, unknown>;\n methods?: Record<string, unknown>;\n implements?: unknown;\n }) => {\n assertInInjectionContext(injectCraft);\n const tokenValue = inject(token); // inject will enable to set inputsKeysSet\n const entriesInputs = entries?.inputs;\n applyEntriesInputs({\n entriesInputs,\n keysSet: inputsKeysSet,\n targetPluggableInputs: pluggableInputs,\n });\n\n // for each methods associated to a source, trigger the targeted method when the source change\n const entriesMethods = entries?.methods;\n const connectedMethodNames = new Set<string>();\n if (entriesMethods) {\n Object.entries(entriesMethods).forEach(([methodName, source]) => {\n connectedMethodNames.add(methodName);\n effect(() => {\n const newValue = (source as Function)();\n untracked(() => {\n if (newValue !== undefined) {\n (tokenValue as any)[methodName](newValue);\n }\n });\n });\n });\n }\n\n // Filter out connected methods from the returned store\n if (connectedMethodNames.size > 0) {\n const filteredStore = Object.keys(tokenValue).reduce((acc, key) => {\n if (!connectedMethodNames.has(key)) {\n acc[key] = (tokenValue as any)[key];\n }\n return acc;\n }, {} as any);\n return filteredStore;\n }\n\n return tokenValue;\n },\n [craftNameCraft]: (\n pluggableConfig?: (context: ContextConstraints) => {\n inputs?: Record<string, unknown>;\n methods?: Record<string, Function>;\n },\n ) => {\n return (\n hostCloud: CloudProxy<Record<string, unknown>>,\n storeConfig: StoreConfigConstraints,\n ) => {\n const specificCraftContextFn = (\n contextData: ContextInput<ContextConstraints>,\n injector: Injector,\n storeConfig: StoreConfigConstraints,\n _cloudProxy: CloudProxy<Record<string, unknown>>,\n ) => {\n const entries =\n pluggableConfig?.({\n ...contextData.context._inputs,\n ...contextData.context._injections,\n ...contextData.context._sources,\n ...contextData.context.props,\n } as any) ?? {};\n\n const entriesInputs = entries?.inputs;\n\n let storeContext: ContextConstraints | undefined = undefined;\n\n if (options?.providedIn !== 'root') {\n // Create a new pluggableInputs for each host to avoid sharing state\n const localPluggableInputs = createSignalProxy(signal({}));\n const { context } = mergeContextAndProps({\n factoriesList,\n pluggableInputs: localPluggableInputs,\n injector,\n storeConfig,\n _cloudProxy,\n });\n storeContext = context;\n\n // Use a local keys set and apply entries to the local pluggable inputs\n const localInputsKeysSet = new Set(\n Object.keys((storeContext as ContextConstraints)._inputs),\n );\n applyEntriesInputs({\n entriesInputs,\n keysSet: localInputsKeysSet,\n targetPluggableInputs: localPluggableInputs,\n });\n } else {\n const _getOrGenerateStore = inject(token);\n storeContext = sharedContext;\n\n inputsKeysSet = new Set(\n Object.keys((storeContext as ContextConstraints)._inputs),\n );\n applyEntriesInputs({\n entriesInputs,\n keysSet: inputsKeysSet,\n targetPluggableInputs: pluggableInputs,\n });\n }\n\n const destroyRef = inject(DestroyRef);\n\n Object.entries(entries?.methods ?? {}).forEach(\n ([methodNameToConnect, connectedSource]) => {\n if (isSignal(connectedSource)) {\n effect(() => {\n const value = connectedSource();\n console.log('value', value);\n if (!value) {\n return;\n }\n storeContext?.methods[methodNameToConnect](connectedSource());\n });\n } else if (\n 'subscribe' in connectedSource &&\n typeof connectedSource.subscribe === 'function'\n ) {\n const sub = (\n connectedSource.subscribe as EventEmitter<unknown>['subscribe']\n )((value) => storeContext?.methods[methodNameToConnect](value));\n destroyRef.onDestroy(() => sub.unsubscribe());\n }\n },\n );\n const connectedMethodNames = new Set(\n Object.keys(entries?.methods ?? {}) as string[],\n );\n const storeContextWithoutConnectedMethods = {\n ...storeContext,\n methods: Object.entries(storeContext?.methods ?? {}).reduce(\n (acc, [methodName, method]) => {\n if (connectedMethodNames.has(methodName)) {\n return acc;\n }\n acc[methodName] = method;\n\n return acc;\n },\n {} as Record<string, Function>,\n ),\n };\n\n Object.assign(hostCloud, _cloudProxy);\n\n const resultDebug = Object.assign(\n storeContextWithoutConnectedMethods as ContextConstraints,\n extractedStandaloneOutputs,\n );\n return resultDebug;\n };\n\n const craftResult = Object.assign(\n specificCraftContextFn,\n extractedStandaloneOutputs,\n );\n\n return craftResult;\n };\n },\n [`${capitalizedName}Craft`]: token,\n [`provide${capitalizedName}Craft`]: provideCraftFn,\n ...extractedStandaloneOutputs,\n } as ToCraftOutputs<\n _EmptyContext[],\n EmptyStandaloneContext[],\n {\n name: string;\n providedIn: ProvidedInOption;\n }\n >;\n}\n\nfunction applyEntriesInputs({\n entriesInputs,\n keysSet,\n targetPluggableInputs,\n}: {\n entriesInputs: Record<string, unknown> | undefined;\n keysSet: Set<string> | undefined;\n targetPluggableInputs: { $patch: (v: any) => void };\n}) {\n if (!entriesInputs) return;\n let hasInputs = false;\n const inputs = Array.from(keysSet ?? []).reduce(\n (acc, inputKey) => {\n if (inputKey in entriesInputs) {\n hasInputs = true;\n const value = (entriesInputs as any)[inputKey];\n if (value !== EXTERNALLY_PROVIDED) {\n acc[inputKey] = value;\n }\n }\n return acc;\n },\n {} as Record<string, unknown>,\n );\n if (hasInputs) {\n targetPluggableInputs.$patch(inputs as ContextConstraints['_inputs']);\n }\n}\n\nfunction mergeContextAndProps({\n factoriesList,\n pluggableInputs,\n injector,\n storeConfig,\n _cloudProxy,\n}: {\n factoriesList: CraftFactory<\n [ContextConstraints],\n StoreConfigConstraints,\n any,\n any\n >[];\n pluggableInputs: SignalProxy<{}, true>;\n injector: Injector;\n storeConfig: StoreConfigConstraints;\n _cloudProxy: CloudProxy<Record<string, unknown>>;\n}): { propsAndMethods: any; context: any } {\n return factoriesList.reduce(\n (acc, factory) => {\n const result = (\n factory as CraftFactory<\n [ContextConstraints],\n StoreConfigConstraints,\n ContextConstraints,\n StandaloneOutputsConstraints\n >\n )(_cloudProxy, storeConfig)(\n {\n context: { ...acc.context, _inputs: pluggableInputs },\n },\n injector,\n storeConfig,\n _cloudProxy,\n );\n Object.entries(result._inputs).forEach(([key, value]) => {\n const hasValue = pluggableInputs.$ref(key as never);\n if (!hasValue) {\n pluggableInputs.$patch({ [key]: value } as any);\n }\n });\n\n Object.assign(_cloudProxy, result._cloudProxy);\n return {\n context: {\n _inputs: { ...acc.context._inputs, ...result._inputs },\n _injections: {\n ...acc.context._injections,\n ...result._injections,\n },\n props: {\n ...acc.context.props,\n ...result.props,\n },\n methods: {\n ...acc.context.methods,\n ...result.methods,\n },\n _query: {\n ...acc.context._query,\n ...result._query,\n },\n _mutation: {\n ...acc.context._mutation,\n ...result._mutation,\n },\n _queryParams: {\n ...acc.context._queryParams,\n ...result._queryParams,\n },\n _sources: {\n ...acc.context._sources,\n ...result._sources,\n },\n _AsyncProcess: {\n ...acc.context._AsyncProcess,\n ...result._AsyncProcess,\n },\n _cloudProxy: {\n ...acc.context._cloudProxy,\n ...result._cloudProxy,\n },\n _dependencies: {\n ...acc.context._dependencies,\n ...result._dependencies,\n },\n _error: {\n ...acc.context._error,\n ...result._error,\n },\n },\n propsAndMethods: {\n ...acc.propsAndMethods,\n ...result.props,\n ...result.methods,\n },\n };\n },\n {\n context: {\n props: {},\n methods: {},\n _inputs: {}, // passing pluggableInputs here seems to not works\n _queryParams: {},\n _sources: {},\n _injections: {},\n _mutation: {},\n _query: {},\n _AsyncProcess: {},\n _cloudProxy: {},\n _dependencies: {},\n _error: {},\n } as _EmptyContext,\n propsAndMethods: {},\n } as {\n context: _EmptyContext;\n propsAndMethods: {};\n },\n );\n}\n","import {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { capitalize } from './util/util';\nimport {\n FilterMethodsBoundToSources,\n Prettify,\n UnionToTuple,\n} from './util/util.type';\nimport { AsyncProcessRef } from './async-process';\n\ntype SpecificCraftAsyncProcessesOutputs<AsyncProcess extends {}> =\n PartialContext<{\n props: {\n [key in keyof AsyncProcess]: Prettify<Omit<AsyncProcess[key], 'method'>>;\n };\n methods: FilterMethodsBoundToSources<\n AsyncProcess,\n UnionToTuple<keyof AsyncProcess>,\n 'set',\n 'method'\n >;\n _AsyncProcess: {\n [key in keyof AsyncProcess]: Prettify<Omit<AsyncProcess[key], 'method'>>;\n };\n }>;\n\ntype craftAsyncProcessesOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n AsyncProcess extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftAsyncProcessesOutputs<AsyncProcess>\n>;\n\n/**\n * Creates async method definitions for use within a craft store, enabling reactive management of asynchronous operations.\n *\n * This function integrates multiple `AsyncProcess()` instances into a craft store by:\n * - Registering async methods as a group with automatic state tracking\n * - Generating prefixed `set` methods for each async method (e.g., `setMethodName`)\n * - Exposing async method state signals (value, status, error, isLoading)\n * - Supporting both method-based and source-based async method triggering\n * - Managing async methods with identifiers for parallel execution\n * - Enabling insertions for extending functionality (persistence, etc.)\n *\n * @remarks\n * **Naming Convention:**\n * - Async methods are accessible as: `store.methodName` (returns signals and state)\n * - Trigger methods are prefixed: `store.setMethodName(args)`\n * - Source-based async methods (bound to sources) don't expose `set` methods\n *\n * **Difference from Mutations:**\n * - **Async Methods**: General-purpose async operations without automatic query coordination\n * - **Mutations**: Server data modifications with built-in query synchronization patterns\n * - Use async methods for operations like debounced search, background tasks\n * - Use mutations for CRUD operations that should update query caches\n *\n * **Use Cases:**\n * - **Debounced operations**: Search, validation, autosave with delay\n * - **Background tasks**: Processing, computation without blocking UI\n * - **Third-party APIs**: External service calls with status tracking\n * - **Polling**: Periodic checks or updates\n * - **Cancellable operations**: Long-running tasks with abort capability\n *\n * **Context Access:**\n * The async methods factory receives full access to the craft context:\n * - Sources: Bind async methods to sources for automatic execution\n * - Queries: Access query state for conditional logic\n * - States: Read and react to state changes\n * - Injections: Access Angular services and dependencies\n *\n * **Store Integration:**\n * - Async method state accessible as: `store.methodName.value()`, `store.methodName.status()`\n * - Trigger async methods: `store.setMethodName(args)`\n * - With identifier: `store.methodName.select(id)` for individual instances\n * - Context access: Other craft entries can access async methods for coordination\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template AsyncProcess - Record of async method names to async method instances\n *\n * @param AsyncProcessFactory - Factory function that receives the craft context and returns a record of async methods.\n * Has access to all other craft entries (sources, queries, states, injections) defined before it.\n *\n * @returns A craft factory utility that integrates async methods into the store with:\n * - `store.methodName`: Async method state and signals\n * - `store.setMethodName(args)`: Method to trigger the async operation (for method-based async methods)\n * - Full type safety for async method parameters and results\n *\n * @example\n * Basic method-based async method\n * ```ts\n * const delay = asyncProcess({\n * method: (delay: number) => delay,\n * loader: async ({ params }) => {\n * await new Promise(resolve => setTimeout(resolve, 500)); // Simulate delay\n * return 'done';\n * },\n * });\n *\n * // Trigger manually\n * delay.method(500);\n *\n * // Track state\n * console.log(delay.status()); // 'loading'\n * console.log(delay.isLoading()); // true\n *\n * // After completion\n * console.log(delay.status()); // 'resolved'\n * console.log(delay.value()); // 'done'\n * console.log(delay.hasValue()); // true\n * ```\n *\n * @example\n * Source-based async method for automatic execution\n * ```ts\n * const delaySource = source<number>();\n *\n * const delay = asyncProcess({\n * method: afterRecomputation(delaySource, (term) => term),\n * loader: async ({ params }) => {\n * // Debounce at source level\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done';\n * },\n * });\n *\n * // Triggers automatically when source emits\n * delaySource.set(500);\n * // -> delay executes automatically\n *\n * // No manual method, only source\n * console.log(delay.source); // ReadonlySource<number>\n * console.log(delay.status()); // Current state\n * ```\n *\n * @example\n * Async method with identifier for parallel operations\n * ```ts\n * const delayById = asyncProcess({\n * method: (id: string) => id,\n * identifier: (id) => id,\n * loader: async () => {\n * await new Promise(resolve => setTimeout(resolve, 300));\n * return 'done'; // Simulate delay\n * },\n * });\n *\n * delayById.method('id1');\n * delayById.method('id2');\n * delayById.method('id3');\n *\n * // Access individual states\n * const delay1 = delayById.select('id1');\n * console.log(delay1?.status()); // 'loading' or 'resolved'\n * console.log(delay1?.value()); // 'done'\n *\n * const delay2 = delayById.select('id2');\n * console.log(delay2?.status()); // Independent state\n * ```\n *\n * @example\n * Calling async js native API\n * ```ts\n * const shareContent = asyncProcess({\n * method: (payload: { title: string, url: string }) => payload,\n * stream: async ({ params }) => {\n * return navigator.share(params);\n * },\n * }, ({resource}) => ({isMenuOpen: computed(() => resource.status() === 'loading')} ));\n *\n * // Trigger shareContent\n * shareContent.method({ title: 'Hello AI!', url: 'https://example.com' });\n * shareContent.isMenuOpen(); // true while loading\n *\n * ```\n */\nexport function craftAsyncProcesses<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n AsyncProcess extends {},\n>(\n AsyncProcessFactory: (context: CraftFactoryEntries<Context>) => AsyncProcess,\n): craftAsyncProcessesOutputs<Context, StoreConfig, AsyncProcess> {\n return (_cloudProxy) => (contextData) => {\n const AsyncProcess = AsyncProcessFactory(\n craftFactoryEntries(contextData),\n ) as Record<\n string,\n AsyncProcessRef<\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown\n >\n >;\n\n const { methods, resourceRefs } = Object.entries(AsyncProcess ?? {}).reduce(\n (acc, [methodName, AsyncProcessRef]) => {\n const methodValue =\n 'method' in AsyncProcessRef ? AsyncProcessRef.method : undefined;\n if (!methodValue) {\n acc.resourceRefs[methodName] = AsyncProcessRef;\n return acc;\n }\n acc.resourceRefs[methodName] = {\n ...AsyncProcessRef,\n };\n acc.methods[`set${capitalize(methodName)}`] = methodValue as Function;\n return acc;\n },\n {\n methods: {},\n resourceRefs: {},\n } as {\n resourceRefs: Record<\n string,\n Omit<\n AsyncProcessRef<\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown\n >,\n 'method' | 'source'\n >\n >;\n methods: Record<string, Function>;\n },\n );\n\n return partialContext({\n props: resourceRefs,\n methods,\n _AsyncProcess: resourceRefs,\n }) as unknown as SpecificCraftAsyncProcessesOutputs<AsyncProcess>;\n };\n}\n","import { Signal } from '@angular/core';\nimport {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\n\ntype SpecificCraftComputedOutputs<Computed extends {}> = PartialContext<{\n props: Computed;\n}>;\n\ntype CraftComputedStatesOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Computed extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftComputedOutputs<Computed>\n>;\n\n/**\n * Creates computed signals derived from other craft store entries (queries, mutations, states).\n *\n * This function enables reactive derived values in craft stores by:\n * - Creating computed signals that automatically update when dependencies change\n * - Deriving values from queries, mutations, states, and other computed signals\n * - Exposing computed values directly on the store (no prefix)\n * - Providing full type safety for computed values\n * - Enabling complex transformations and combinations of store data\n * - Supporting memo-ization for performance optimization\n *\n * @remarks\n * **Naming Convention:**\n * - Computed signals are accessible directly: `store.computedName()`\n * - No prefix added (unlike queries/mutations)\n * - Access pattern is identical to regular Angular signals\n *\n * **Use Cases:**\n * - **Derived data**: Calculate values based on query/state results (totals, counts, filtered lists)\n * - **Data transformation**: Format or reshape data from queries\n * - **Aggregation**: Combine data from multiple queries or states\n * - **Status derivation**: Compute loading states from multiple queries\n * - **Validation**: Derive validation status from form states\n * - **UI state**: Calculate UI flags based on multiple conditions\n *\n * **Context Access:**\n * - Computed factory receives full access to the craft context\n * - Can access queries, mutations, states, sources, and other computed values\n * - Context entries are accessed as signals: `context.queryName()`, `context.stateName()`\n *\n * **Reactive Behavior:**\n * - Computed signals automatically update when dependencies change\n * - Only recompute when accessed and dependencies have changed (memo-ized)\n * - Follow Angular's computed signal semantics\n * - Can be used in templates and effects like any signal\n *\n * **Performance:**\n * - Computed values are cached and only recompute when necessary\n * - Multiple accesses without dependency changes don't trigger recomputation\n * - Efficient for expensive calculations or transformations\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Computed - Record of computed signal names to signal types\n *\n * @param computedFactory - Factory function that receives the craft context and returns a record of computed signals.\n * Has access to all other craft entries (queries, mutations, states) defined before it.\n *\n * @returns A craft factory utility that:\n * - Creates computed signals based on store data\n * - Exposes them directly on the store\n * - Provides full type safety for computed values\n *\n * @example\n * Basic computed values from state\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('count', () => state(0)),\n * craftComputedStates(({ count }) => ({\n * doubled: computed(() => count() * 2),\n * isEven: computed(() => count() % 2 === 0),\n * message: computed(() => `Count is ${count()}`),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * console.log(store.doubled()); // 0\n * console.log(store.isEven()); // true\n *\n * store.setCount(5);\n * console.log(store.doubled()); // 10\n * console.log(store.isEven()); // false\n * console.log(store.message()); // 'Count is 5'\n * ```\n *\n * @example\n * Computed values from query results\n * ```ts\n * type Todo = { id: string; text: string; done: boolean };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('todos', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json() as Todo[];\n * },\n * })\n * ),\n * craftComputedStates(({ todos }) => ({\n * completedCount: computed(() => {\n * const list = todos.value();\n * return list?.filter(t => t.done).length ?? 0;\n * }),\n * pendingCount: computed(() => {\n * const list = todos.value();\n * return list?.filter(t => !t.done).length ?? 0;\n * }),\n * totalCount: computed(() => todos.value()?.length ?? 0),\n * allCompleted: computed(() => {\n * const list = todos.value();\n * return list ? list.length > 0 && list.every(t => t.done) : false;\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Use in template\n * // <div>{{ store.completedCount() }} / {{ store.totalCount() }} completed</div>\n * // <button [disabled]=\"store.allCompleted()\">Complete All</button>\n * ```\n *\n * @example\n * Combining multiple queries\n * ```ts\n * type User = { id: string; name: string };\n * type Post = { id: string; userId: string; title: string };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('users', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/users');\n * return response.json() as User[];\n * },\n * })\n * ),\n * craftQuery('posts', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/posts');\n * return response.json() as Post[];\n * },\n * })\n * ),\n * craftComputedStates(({ users, posts }) => ({\n * postsWithAuthors: computed(() => {\n * const userList = users.value();\n * const postList = posts.value();\n *\n * if (!userList || !postList) return [];\n *\n * return postList.map(post => ({\n * ...post,\n * author: userList.find(u => u.id === post.userId),\n * }));\n * }),\n * userPostCount: computed(() => {\n * const postList = posts.value();\n * if (!postList) return new Map();\n *\n * return postList.reduce((map, post) => {\n * map.set(post.userId, (map.get(post.userId) ?? 0) + 1);\n * return map;\n * }, new Map<string, number>());\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Automatically combines data from both queries\n * const enrichedPosts = store.postsWithAuthors();\n * const postCounts = store.userPostCount();\n * ```\n *\n * @example\n * Loading state aggregation\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('sales', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/sales');\n * return response.json();\n * },\n * })\n * ),\n * craftQuery('analytics', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/analytics');\n * return response.json();\n * },\n * })\n * ),\n * craftComputedStates(({ sales, analytics }) => ({\n * isLoading: computed(() =>\n * sales.isLoading() || analytics.isLoading()\n * ),\n * hasError: computed(() =>\n * sales.error() !== undefined || analytics.error() !== undefined\n * ),\n * allLoaded: computed(() =>\n * sales.hasValue() && analytics.hasValue()\n * ),\n * errorMessage: computed(() => {\n * const salesError = sales.error();\n * const analyticsError = analytics.error();\n *\n * if (salesError) return `Sales error: ${salesError.message}`;\n * if (analyticsError) return `Analytics error: ${analyticsError.message}`;\n * return null;\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Use in template for unified loading state\n * // @if (store.isLoading()) { <spinner /> }\n * // @if (store.hasError()) { <error>{{ store.errorMessage() }}</error> }\n * // @if (store.allLoaded()) { <dashboard /> }\n * ```\n *\n * @example\n * Chaining computed values\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('items', () =>\n * state([] as Array<{ id: string; price: number; quantity: number }>)\n * ),\n * craftComputedStates(({ items }) => ({\n * subtotal: computed(() =>\n * items().reduce((sum, item) => sum + item.price * item.quantity, 0)\n * ),\n * })),\n * craftComputedStates(({ subtotal }) => ({\n * // Can depend on other computed values\n * tax: computed(() => subtotal() * 0.1),\n * shipping: computed(() => subtotal() > 100 ? 0 : 10),\n * })),\n * craftComputedStates(({ subtotal, tax, shipping }) => ({\n * // Combine multiple computed values\n * total: computed(() => subtotal() + tax() + shipping()),\n * formatted: computed(() => ({\n * subtotal: `$${subtotal().toFixed(2)}`,\n * tax: `$${tax().toFixed(2)}`,\n * shipping: shipping() === 0 ? 'FREE' : `$${shipping().toFixed(2)}`,\n * total: `$${(subtotal() + tax() + shipping()).toFixed(2)}`,\n * })),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * console.log(store.formatted());\n * // { subtotal: '$0.00', tax: '$0.00', shipping: '$10.00', total: '$10.00' }\n * ```\n *\n * @example\n * Data transformation and filtering\n * ```ts\n * type Product = {\n * id: string;\n * name: string;\n * category: string;\n * price: number;\n * inStock: boolean;\n * };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('products', () =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/products');\n * return response.json() as Product[];\n * },\n * })\n * ),\n * craftState('selectedCategory', () => state<string | null>(null)),\n * craftState('maxPrice', () => state<number | null>(null)),\n * craftComputedStates(({ products, selectedCategory, maxPrice }) => ({\n * filteredProducts: computed(() => {\n * const list = products.value();\n * if (!list) return [];\n *\n * let filtered = list;\n *\n * const category = selectedCategory();\n * if (category) {\n * filtered = filtered.filter(p => p.category === category);\n * }\n *\n * const price = maxPrice();\n * if (price !== null) {\n * filtered = filtered.filter(p => p.price <= price);\n * }\n *\n * return filtered;\n * }),\n * availableProducts: computed(() => {\n * const list = products.value();\n * return list?.filter(p => p.inStock) ?? [];\n * }),\n * categories: computed(() => {\n * const list = products.value();\n * if (!list) return [];\n *\n * return [...new Set(list.map(p => p.category))];\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Filters update reactively\n * store.setSelectedCategory('electronics');\n * store.setMaxPrice(500);\n * const filtered = store.filteredProducts(); // Automatically filtered\n * ```\n *\n * @example\n * Validation computed values\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('email', () => state('')),\n * craftState('password', () => state('')),\n * craftState('confirmPassword', () => state('')),\n * craftComputedStates(({ email, password, confirmPassword }) => ({\n * isEmailValid: computed(() => {\n * const value = email();\n * return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n * }),\n * isPasswordValid: computed(() => {\n * const value = password();\n * return value.length >= 8;\n * }),\n * doPasswordsMatch: computed(() => {\n * return password() === confirmPassword();\n * }),\n * isFormValid: computed(() => {\n * const emailValid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email());\n * const passwordValid = password().length >= 8;\n * const passwordsMatch = password() === confirmPassword();\n *\n * return emailValid && passwordValid && passwordsMatch;\n * }),\n * validationErrors: computed(() => {\n * const errors: string[] = [];\n *\n * if (email() && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email())) {\n * errors.push('Invalid email format');\n * }\n * if (password() && password().length < 8) {\n * errors.push('Password must be at least 8 characters');\n * }\n * if (confirmPassword() && password() !== confirmPassword()) {\n * errors.push('Passwords do not match');\n * }\n *\n * return errors;\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Use in template\n * // <button [disabled]=\"!store.isFormValid()\">Submit</button>\n * // @for (error of store.validationErrors(); track error) {\n * // <div class=\"error\">{{ error }}</div>\n * // }\n * ```\n */\nexport function craftComputedStates<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Computed extends {},\n>(\n computedFactory: (context: CraftFactoryEntries<Context>) => Computed,\n): CraftComputedStatesOutputs<Context, StoreConfig, Computed> {\n return () => (contextData) => {\n const computedValues = computedFactory(\n craftFactoryEntries(contextData),\n ) as Record<string, Signal<unknown>>;\n\n return partialContext({\n props: computedValues,\n }) as SpecificCraftComputedOutputs<Computed>;\n };\n}\n","import { InjectionToken, Type } from '@angular/core';\nimport {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\n\ntype ProviderTokenWithoutAbstract<T> = Type<T> | InjectionToken<T>;\n\ntype InferProvidedType<T> =\n T extends ProviderTokenWithoutAbstract<infer U> ? U : never;\n\ntype SpecificCraftInjectionsOutputs<Injections extends {}> = PartialContext<{\n _injections: {\n [key in keyof Injections as Uncapitalize<key & string>]: InferProvidedType<\n Injections[key]\n >;\n };\n}>;\n\ntype CraftInputsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Injections extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftInjectionsOutputs<Injections>\n>;\n\n// todo checker si ok avec les token si valeur bien infer / service / token et générics\n\n/**\n * Injects Angular services and tokens into a craft store, making them accessible to all craft entries.\n *\n * This function integrates Angular's dependency injection system into craft stores by:\n * - Injecting services, injection tokens, and providers\n * - Making injected dependencies accessible in all craft entries (queries, mutations, states)\n * - Supporting generic services with type parameters\n * - Automatically converting injection keys to camelCase for context access\n * - Providing full type safety for injected dependencies\n * - Accessing services outside of direct injection context\n *\n * @remarks\n * **Naming Convention:**\n * - Define injections with PascalCase keys: `{ MyService, UserRepository }`\n * - Access in context with camelCase: `context.myService`, `context.userRepository`\n * - Automatic conversion preserves type information\n *\n * **Use Cases:**\n * - **Service integration**: Access Angular services (HttpClient, Router, etc.) in queries/mutations\n * - **API clients**: Inject custom API service classes for data fetching\n * - **State services**: Access existing Angular services that manage state\n * - **Configuration**: Inject configuration tokens and environment settings\n * - **Third-party libraries**: Access library services and utilities\n * - **Testing**: Mock services by providing test implementations\n *\n * **Injection Types:**\n * - **Services**: Injectable classes marked with `@Injectable()`\n * - **Injection Tokens**: `InjectionToken<T>` for non-class dependencies\n * - **Generic Services**: Services with type parameters `Service<T>`\n * - **Abstract Classes**: Base classes with implementations provided elsewhere\n *\n * **Context Access:**\n * - Injections available in all craft entries via context parameter\n * - Access pattern: `context.serviceName` (lowercase first letter)\n * - Can access other context entries in the injection factory function\n *\n * **Reactive Integration:**\n * - Services can expose signals that queries/mutations react to\n * - Service methods can be called from query loaders or mutation handlers\n * - Injected services maintain their own lifecycle and state\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Injections - Record of injection keys to provider types\n *\n * @param injections - Factory function that receives the craft context and returns a record of injections.\n * Keys should be PascalCase (matching service/token names), values should be service classes or injection tokens.\n * Has access to all other craft entries defined before it.\n *\n * @returns A craft factory utility that:\n * - Injects all specified dependencies using Angular's injector\n * - Makes them accessible in camelCase in the craft context\n * - Provides full type safety for injected services\n *\n * @example\n * Basic service injection\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class UserApiService {\n * constructor(private http: HttpClient) {}\n *\n * getUser(id: string) {\n * return this.http.get<User>(`/api/users/${id}`);\n * }\n *\n * updateUser(user: User) {\n * return this.http.patch<User>(`/api/users/${user.id}`, user);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * UserApiService, // Inject the service\n * })),\n * craftQuery('user', ({ userApiService }) =>\n * query({\n * params: () => 'user-123',\n * loader: async ({ params }) => {\n * // Use the injected service\n * return firstValueFrom(userApiService.getUser(params));\n * },\n * })\n * ),\n * craftMutations(({ userApiService }) => ({\n * updateUser: mutation({\n * method: (user: User) => user,\n * loader: async ({ params }) => {\n * // Use the injected service in mutation\n * return firstValueFrom(userApiService.updateUser(params));\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n * // Service is used internally by queries and mutations\n * ```\n *\n * @example\n * Multiple service injections\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class AuthService {\n * currentUser = signal<User | null>(null);\n *\n * isAuthenticated() {\n * return this.currentUser() !== null;\n * }\n * }\n *\n * @Injectable({ providedIn: 'root' })\n * class ApiClient {\n * constructor(private http: HttpClient) {}\n *\n * get<T>(url: string) {\n * return this.http.get<T>(url);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * AuthService,\n * ApiClient,\n * Router, // Can inject Angular services too\n * })),\n * craftQuery('protectedData', ({ authService, apiClient }) =>\n * query({\n * params: () => authService.currentUser()?.id,\n * loader: async ({ params }) => {\n * if (!params) return null;\n * return firstValueFrom(apiClient.get(`/api/protected/${params}`));\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Queries automatically react to authService.currentUser changes\n * ```\n *\n * @example\n * Injection tokens for configuration\n * ```ts\n * interface AppConfig {\n * apiUrl: string;\n * timeout: number;\n * }\n *\n * const APP_CONFIG = new InjectionToken<AppConfig>('APP_CONFIG', {\n * providedIn: 'root',\n * factory: () => ({\n * apiUrl: 'https://api.example.com',\n * timeout: 5000,\n * }),\n * });\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * AppConfig: APP_CONFIG, // Inject token\n * })),\n * craftQuery('data', ({ appConfig }) =>\n * query({\n * params: () => ({}),\n * loader: async () => {\n * // Use config from token\n * const response = await fetch(`${appConfig.apiUrl}/data`, {\n * signal: AbortSignal.timeout(appConfig.timeout),\n * });\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Queries use configuration from injection token\n * ```\n *\n * @example\n * Generic service injection\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class Repository<T> {\n * private cache = new Map<string, T>();\n *\n * get(id: string): T | undefined {\n * return this.cache.get(id);\n * }\n *\n * set(id: string, value: T): void {\n * this.cache.set(id, value);\n * }\n * }\n *\n * type Product = { id: string; name: string; price: number };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * ProductRepository: Repository<Product>, // Specify generic type\n * })),\n * craftQuery('product', ({ productRepository }) =>\n * query({\n * params: () => 'product-1',\n * loader: async ({ params }) => {\n * // Check cache first\n * const cached = productRepository.get(params);\n * if (cached) return cached;\n *\n * // Fetch and cache\n * const response = await fetch(`/api/products/${params}`);\n * const product = await response.json();\n * productRepository.set(params, product);\n * return product;\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // productRepository is typed as Repository<Product>\n * ```\n *\n * @example\n * Service with signals for reactive state\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class FilterService {\n * searchTerm = signal('');\n * selectedCategory = signal<string | null>(null);\n *\n * setSearch(term: string) {\n * this.searchTerm.set(term);\n * }\n *\n * setCategory(category: string | null) {\n * this.selectedCategory.set(category);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * FilterService,\n * })),\n * craftQuery('products', ({ filterService }) =>\n * query({\n * params: () => ({\n * search: filterService.searchTerm(),\n * category: filterService.selectedCategory(),\n * }),\n * loader: async ({ params }) => {\n * const query = new URLSearchParams({\n * search: params.search,\n * category: params.category ?? '',\n * });\n * const response = await fetch(`/api/products?${query}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Query automatically re-executes when filter signals change\n *\n * // In a component\n * export class FilterComponent {\n * filterService = inject(FilterService);\n *\n * onSearch(term: string) {\n * this.filterService.setSearch(term);\n * // Store query reacts automatically\n * }\n * }\n * ```\n *\n * @example\n * Accessing context entries in injection factory\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class LoggingService {\n * log(message: string) {\n * console.log(`[LOG] ${message}`);\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * error: source<Error>(),\n * }),\n * craftInject(({ error }) => {\n * // Can access previous context entries\n * return {\n * LoggingService,\n * };\n * }),\n * craftState('errorLog', ({ error, loggingService }) =>\n * state([] as string[], {\n * bindSources: {\n * error: (errors, err) => {\n * // Use injected service\n * loggingService.log(`Error occurred: ${err.message}`);\n * return [...errors, err.message];\n * },\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * store.setError(new Error('Something went wrong'));\n * // Logging service is used to log the error\n * ```\n *\n * @example\n * Complex service composition\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * class CacheService {\n * private cache = new Map<string, { data: unknown; timestamp: number }>();\n *\n * get<T>(key: string, maxAge: number): T | null {\n * const entry = this.cache.get(key);\n * if (!entry) return null;\n *\n * if (Date.now() - entry.timestamp > maxAge) {\n * this.cache.delete(key);\n * return null;\n * }\n *\n * return entry.data as T;\n * }\n *\n * set(key: string, data: unknown): void {\n * this.cache.set(key, { data, timestamp: Date.now() });\n * }\n * }\n *\n * @Injectable({ providedIn: 'root' })\n * class HttpService {\n * constructor(\n * private http: HttpClient,\n * private cache: CacheService\n * ) {}\n *\n * async fetchWithCache<T>(url: string, cacheKey: string): Promise<T> {\n * // Check cache (5 minute expiry)\n * const cached = this.cache.get<T>(cacheKey, 5 * 60 * 1000);\n * if (cached) return cached;\n *\n * // Fetch and cache\n * const data = await firstValueFrom(this.http.get<T>(url));\n * this.cache.set(cacheKey, data);\n * return data;\n * }\n * }\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInject(() => ({\n * HttpService,\n * })),\n * craftQuery('userData', ({ httpService }) =>\n * query({\n * params: () => 'user-123',\n * loader: async ({ params }) => {\n * // Service handles caching internally\n * return httpService.fetchWithCache(\n * `/api/users/${params}`,\n * `user-${params}`\n * );\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n * // Queries benefit from service's internal caching\n * ```\n */\nexport function craftInject<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Injections extends {},\n>(\n injections: (entries: CraftFactoryEntries<Context>) => Injections,\n): CraftInputsOutputs<Context, StoreConfig, Injections> {\n return () => (contextData, injector) => {\n const injectedInjections = Object.entries(\n injections(craftFactoryEntries(contextData)),\n ).reduce(\n (acc, [key, injection]) => ({\n ...acc,\n [uncapitalize(key)]: injector.get(injection as any),\n }),\n {},\n );\n return partialContext({\n _injections: injectedInjections,\n }) as SpecificCraftInjectionsOutputs<Injections>;\n };\n}\n\nfunction uncapitalize(str: string) {\n return str.charAt(0).toLowerCase() + str.slice(1);\n}\n","import { Signal } from '@angular/core';\nimport {\n ContextConstraints,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { Prettify } from './util/util.type';\n\ntype ToSignalObject<T> = {\n [K in keyof T]: Signal<T[K]>;\n};\n\ntype SpecificCraftInputsOutputs<Inputs extends {}> = PartialContext<{\n _inputs: Prettify<ToSignalObject<Inputs>>;\n}>;\n\ntype CraftInputsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Inputs extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftInputsOutputs<Inputs>\n>;\n\n/**\n * Creates input definitions for use within a craft store, enabling dynamic parameter injection from components.\n *\n * This function enables external data to be passed into a craft store by:\n * - Defining a schema of expected input parameters with their types\n * - Converting input values to signals automatically\n * - Making inputs accessible to all craft entries (queries, mutations, states)\n * - Providing type-safe parameter passing from components to store\n * - Enabling reactive updates when input values change\n *\n * @remarks\n * **Use Cases:**\n * - **Dynamic parameters**: Pass component-specific data to queries (e.g., route params, user selections)\n * - **External signals**: Inject signals from parent components or services\n * - **Conditional loading**: Control when queries execute based on input availability\n * - **Multi-instance stores**: Create store instances with different input configurations\n * - **Component coordination**: Share component state with store logic\n *\n * **Input Definition:**\n * - Define inputs as a record of keys with their types\n * - Inputs are automatically converted to signals in the context\n *\n * **Context Access:**\n * - Inputs are accessible in all craft entries via the context parameter\n * - Access as: `context.inputName` in query/mutation/state factories\n * - Inputs are available as signals: `context.inputName()` returns the value\n *\n * **Store Injection:**\n * - When injecting the store, pass actual signal values: `injectCraft({ inputs: { inputName: signal(value) } })`\n * - TypeScript enforces providing all required inputs\n *\n * **Reactive Behavior:**\n * - When input signals change, dependent queries automatically re-execute\n * - Mutations and states can react to input changes\n * - Use with `params: () => context.inputName()` for reactive queries\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Inputs - Record of input names to their value types\n *\n * @param inputs - Schema object defining input names and their types.\n * Values are used for type inference only; actual values are provided during injection.\n *\n * @returns A craft factory utility that:\n * - Adds inputs to the store context for use by other craft entries\n * - Requires input signals to be provided when injecting the store\n * - Provides full type safety for input values\n *\n * @example\n * Basic inputs for dynamic query parameters\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInputs({\n * userId: undefined as string | undefined,\n * }),\n * craftQuery('user', ({ userId }) =>\n * query({\n * params: userId, // Uses the input signal directly\n * loader: async ({ params }) => {\n * if (!params) return undefined;\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * // In a component\n * @Component({\n * selector: 'app-user-profile',\n * template: `\n * @if (store.user.value()) {\n * <div>{{ store.user.value().name }}</div>\n * }\n * `,\n * })\n * export class UserProfileComponent {\n * route = inject(ActivatedRoute);\n *\n * // Create signal from route param\n * userId = toSignal(this.route.params.pipe(map(p => p['id'])));\n *\n * // Inject store with input\n * store = injectCraft({\n * inputs: {\n * userId: this.userId, // Pass the signal\n * },\n * });\n * }\n *\n * // Query automatically executes and re-executes when userId changes\n * ```\n *\n * @example\n * Inputs shared across multiple craft entries\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftInputs({\n * dateRange: undefined as { start: Date; end: Date } | undefined,\n * userId: undefined as string | undefined,\n * }),\n * craftQuery('sales', ({ dateRange, userId }) =>\n * query({\n * params: () => ({ dateRange: dateRange(), userId: userId() }),\n * loader: async ({ params }) => {\n * if (!params.dateRange || !params.userId) return null;\n * const response = await fetch('/api/sales', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * })\n * ),\n * craftQuery('analytics', ({ dateRange, userId }) =>\n * query({\n * params: () => ({ dateRange: dateRange(), userId: userId() }),\n * loader: async ({ params }) => {\n * if (!params.dateRange || !params.userId) return null;\n * const response = await fetch('/api/analytics', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * // Both queries use the same inputs\n * export class DashboardComponent {\n * dateRange = signal<{ start: Date; end: Date } | undefined>(undefined);\n * userId = signal<string | undefined>('user-123');\n *\n * store = injectCraft({\n * inputs: {\n * dateRange: this.dateRange,\n * userId: this.userId,\n * },\n * });\n *\n * // Both queries re-execute when inputs change\n * updateDateRange(start: Date, end: Date) {\n * this.dateRange.set({ start, end });\n * }\n * }\n * ```\n */\nexport function craftInputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Inputs extends {},\n>(inputs: Inputs): CraftInputsOutputs<Context, StoreConfig, Inputs> {\n // todo expose setXInputs as standalone ?\n return () => () => {\n return partialContext({\n _inputs: inputs,\n }) as SpecificCraftInputsOutputs<Inputs>;\n };\n}\n","import {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { UnionToTuple, Prettify } from './util/util.type';\nimport { capitalize } from './util/util';\nimport { FilterMethodsBoundToSources } from './util/util.type';\nimport { MutationRef } from './mutation';\n\ntype SpecificCraftMutationsOutputs<Mutations extends {}> = PartialContext<{\n props: {\n [key in keyof Mutations]: Prettify<Omit<Mutations[key], 'mutate'>>;\n };\n methods: FilterMethodsBoundToSources<\n Mutations,\n UnionToTuple<keyof Mutations>,\n 'mutate',\n 'mutate'\n >;\n _mutation: {\n [key in keyof Mutations]: Mutations[key];\n };\n}>;\n\ntype CraftMutationsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Mutations extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftMutationsOutputs<Mutations>\n>;\n\n/**\n * Creates mutation definitions for use within a craft store, enabling reactive management of server-side data modifications.\n *\n * This function integrates multiple `mutation()` instances into a craft store by:\n * - Registering mutations as a group with automatic state tracking\n * - Generating prefixed `mutate` methods for each mutation (e.g., `mutateMutationName`)\n * - Exposing mutation state signals (value, status, error, isLoading)\n * - Enabling queries to react to mutation changes via `insertReactOnMutation()`\n * - Supporting both method-based and source-based mutation triggering\n * - Managing mutations with identifiers for parallel execution\n *\n * @remarks\n * **Naming Convention:**\n * - Mutations are accessible as: `store.mutationName` (returns signals and state)\n * - Trigger methods are prefixed: `store.mutateMutationName(args)`\n * - Source-based mutations (bound to sources) don't expose `mutate` methods\n *\n * **Use Cases:**\n * - **Data modification**: Create, update, delete operations on server data\n * - **Optimistic updates**: Update UI immediately while mutation executes\n * - **Cache invalidation**: Trigger query reloads after mutations complete\n * - **Batch operations**: Execute multiple mutations with individual state tracking\n * - **Form submissions**: Handle form data submission with loading/error states\n *\n * **Context Access:**\n * The mutations factory receives full access to the craft context:\n * - Sources: Bind mutations to sources for automatic execution\n * - Queries: Access query state for conditional mutation logic\n * - Other mutations: Coordinate between multiple mutations\n * - Injections: Access Angular services and dependencies\n *\n * **Integration with Queries:**\n * - Queries can react to mutations via `insertReactOnMutation()`\n * - Supports optimistic updates, patches, full updates, and reloads\n * - Filtered reactions based on mutation identifiers\n *\n * **Store Integration:**\n * - Mutation state accessible as: `store.mutationName.value()`, `store.mutationName.status()`\n * - Trigger mutations: `store.mutateMutationName(args)`\n * - With identifier: `store.mutationName.select(id)` for individual instances\n * - Context access: Other craft entries can access mutations for coordination\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template Mutations - Record of mutation names to mutation instances\n *\n * @param mutationsFactory - Factory function that receives the craft context and returns a record of mutations.\n * Has access to all other craft entries (sources, queries, inputs, injections) defined before it.\n *\n * @returns A craft factory utility that integrates mutations into the store with:\n * - `store.mutationName`: Mutation state and signals\n * - `store.mutateMutationName(args)`: Method to trigger the mutation (for method-based mutations)\n * - Full type safety for mutation parameters and results\n *\n * @example\n * Basic mutations for CRUD operations\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * createTodo: mutation({\n * method: (data: { text: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/todos', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * updateTodo: mutation({\n * method: (todo: Todo) => todo,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * deleteTodo: mutation({\n * method: (todoId: string) => ({ todoId }),\n * loader: async ({ params }) => {\n * await fetch(`/api/todos/${params.todoId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Create a new todo\n * store.mutateCreateTodo({ text: 'Buy milk' });\n * console.log(store.createTodo.status()); // 'loading'\n *\n * // After completion\n * console.log(store.createTodo.status()); // 'resolved'\n * console.log(store.createTodo.value()); // { id: '1', text: 'Buy milk', ... }\n *\n * // Update an existing todo\n * store.mutateUpdateTodo({ id: '1', text: 'Buy milk and eggs', done: false });\n *\n * // Delete a todo\n * store.mutateDeleteTodo('1');\n * ```\n *\n * @example\n * Mutations with identifiers for parallel execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateUser: mutation({\n * method: (user: User) => user,\n * identifier: (user) => user.id,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Trigger multiple mutations in parallel\n * store.mutateUpdateUser({ id: 'user-1', name: 'Alice' });\n * store.mutateUpdateUser({ id: 'user-2', name: 'Bob' });\n * store.mutateUpdateUser({ id: 'user-3', name: 'Charlie' });\n *\n * // Access individual mutation states\n * const user1Mutation = store.updateUser.select('user-1');\n * console.log(user1Mutation?.status()); // 'loading' or 'resolved'\n * console.log(user1Mutation?.value()); // { id: 'user-1', name: 'Alice', ... }\n *\n * const user2Mutation = store.updateUser.select('user-2');\n * console.log(user2Mutation?.status()); // Independent state\n * ```\n *\n * @example\n * Mutations coordinated with queries via insertReactOnMutation\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * createPost: mutation({\n * method: (data: CreatePostData) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('posts', ({ createPost }) =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/posts');\n * return response.json();\n * },\n * },\n * insertReactOnMutation(createPost, {\n * // Reload posts list when create completes\n * reload: { onMutationResolved: true },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Create a post - posts query reloads automatically\n * store.mutateCreatePost({ title: 'New Post', content: 'Content...' });\n * // -> createPost mutation executes\n * // -> posts query automatically reloads when mutation resolves\n * ```\n *\n * @example\n * Source-based mutations (automatic execution)\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * submitForm: source<FormData>(),\n * }),\n * craftMutations(({ submitForm }) => ({\n * submit: mutation({\n * method: afterRecomputation(submitForm, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Mutation executes automatically when source emits\n * store.setSubmitForm({ name: 'John', email: 'john@example.com' });\n * // -> submit mutation executes automatically\n * // Note: No mutateSubmit method exposed (source-based)\n *\n * // Access mutation state\n * console.log(store.submit.status()); // 'loading'\n * console.log(store.submit.value()); // Result after completion\n * ```\n *\n * @example\n * Mutations accessing other context entries\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('currentUser', () =>\n * query({\n * params: () => currentUserId(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * ),\n * craftMutations(({ currentUser }) => ({\n * updateProfile: mutation({\n * method: (data: ProfileData) => data,\n * loader: async ({ params }) => {\n * // Access current user from query\n * const userId = currentUser.value()?.id;\n * if (!userId) throw new Error('User not loaded');\n *\n * const response = await fetch(`/api/users/${userId}/profile`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Mutation uses current user from query\n * store.mutateUpdateProfile({ bio: 'New bio', avatar: 'avatar.jpg' });\n * ```\n *\n * @example\n * Multiple mutations with different trigger patterns\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * autoSave: source<SaveData>(),\n * }),\n * craftMutations(({ autoSave }) => ({\n * // Manual mutation\n * manualSave: mutation({\n * method: (data: SaveData) => data,\n * loader: async ({ params }) => {\n * await fetch('/api/save', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return { saved: true };\n * },\n * }),\n * // Auto mutation (source-based)\n * autoSave: mutation({\n * method: afterRecomputation(autoSave, (data) => data),\n * loader: async ({ params }) => {\n * await fetch('/api/autosave', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return { autoSaved: true };\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Manual save - explicit call\n * store.mutateManualSave({ content: 'My data' });\n *\n * // Auto save - triggered by source\n * store.setAutoSave({ content: 'Auto saved data' });\n * // No store.mutateAutoSave available (source-based)\n * ```\n *\n * @example\n * Error handling and status tracking\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * uploadFile: mutation({\n * method: (file: File) => file,\n * loader: async ({ params }) => {\n * const formData = new FormData();\n * formData.append('file', params);\n *\n * const response = await fetch('/api/upload', {\n * method: 'POST',\n * body: formData,\n * });\n *\n * if (!response.ok) {\n * throw new Error('Upload failed');\n * }\n *\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Handle upload with status tracking\n * store.mutateUploadFile(selectedFile);\n *\n * // Track upload status\n * effect(() => {\n * const status = store.uploadFile.status();\n * const error = store.uploadFile.error();\n *\n * if (status === 'loading') {\n * console.log('Uploading...');\n * } else if (status === 'resolved') {\n * console.log('Upload complete:', store.uploadFile.value());\n * } else if (status === 'error') {\n * console.error('Upload failed:', error?.message);\n * }\n * });\n * ```\n */\nexport function craftMutations<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Mutations extends {\n [key: string]: {\n kind: 'mutation';\n };\n },\n>(\n mutationsFactory: (context: CraftFactoryEntries<Context>) => Mutations,\n): CraftMutationsOutputs<Context, StoreConfig, Mutations> {\n return (_cloudProxy) => (contextData) => {\n const mutations = mutationsFactory(\n craftFactoryEntries(contextData),\n ) as unknown as Record<\n string,\n MutationRef<unknown, unknown, unknown, unknown, unknown, unknown, unknown>\n >;\n\n const { methods, resourceRefs } = Object.entries(mutations ?? {}).reduce(\n (acc, [methodName, mutationRef]) => {\n const methodValue =\n 'mutate' in mutationRef ? mutationRef.mutate : undefined;\n if (!methodValue) {\n acc.resourceRefs[methodName] = mutationRef;\n return acc;\n }\n acc.resourceRefs[methodName] = mutationRef;\n acc.methods[`mutate${capitalize(methodName)}`] =\n methodValue as Function;\n return acc;\n },\n {\n methods: {},\n resourceRefs: {},\n } as {\n resourceRefs: Record<\n string,\n Omit<\n MutationRef<\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown\n >,\n 'mutate' | 'source'\n >\n >;\n methods: Record<string, Function>;\n },\n );\n\n return partialContext({\n props: resourceRefs,\n methods,\n _mutation: resourceRefs,\n }) as unknown as SpecificCraftMutationsOutputs<Mutations>;\n };\n}\n","import { Injector, isSignal, Signal, WritableSignal } from '@angular/core';\nimport {\n ContextConstraints,\n ContextInput,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { capitalize } from './util/util';\nimport { QueryParamConfig, QueryParamOutput } from './query-param';\nimport { DeferredExtract } from './util/util.type';\n\nexport type SpecificCraftQueryParamOutputs<\n QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n> =\n DeferredExtract<Insertions> extends infer Extracted\n ? Extracted extends { props: unknown; methods: Record<string, Function> }\n ? PartialContext<{\n props: {\n [key in QueryParamsName]: Signal<QueryParamsState>;\n } & {\n [K in keyof QueryParamsState as `${QueryParamsName &\n string}${Capitalize<K & string>}`]: Signal<QueryParamsState[K]>;\n } & {\n [key in keyof Extracted['props'] as `${QueryParamsName &\n string}${Capitalize<key & string>}`]: Extracted['props'][key];\n };\n methods: {\n [key in keyof Extracted['methods'] as `${key & string}${Capitalize<\n QueryParamsName & string\n >}`]: Extracted['methods'][key];\n };\n _queryParams: {\n [K in QueryParamsName]: {\n config: QueryParamsType;\n state: WritableSignal<QueryParamsState>;\n };\n };\n }>\n : never\n : never;\n\ntype SpecificCraftQueryParamStandaloneOutputs<\n QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n> = {\n [K in QueryParamsName as `set${Capitalize<K>}QueryParams`]: <\n T extends Partial<{\n [K in keyof QueryParamsState]: QueryParamsState[K];\n }>,\n >(\n params: T,\n ) => T;\n};\n\ntype CraftQueryParamOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftQueryParamOutputs<\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >,\n SpecificCraftQueryParamStandaloneOutputs<\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >\n>;\n\n/**\n * Creates a craft factory for reactive query parameter management integrated with the craft store.\n *\n * This function integrates query parameter management into a craft store by:\n * - Creating typed signals for each query parameter prefixed with the provided name\n * - Exposing methods to update query parameters\n * - Providing a standalone method to serialize query params for navigation outside injection context\n * - Synchronizing with URL query parameters automatically\n *\n * @remarks\n * **Important:** The `queryParamFactory` function must return a `queryParam()` call.\n * Since `queryParam()` requires an injection context, `craftQueryParam` handles this by:\n * - Calling the factory within an injection context to create the reactive query param manager\n * - Calling the factory outside injection context to extract the configuration for standalone methods\n *\n * **Warning:** Be careful to avoid query params key collisions. (There is no verification yet)\n *\n * @param queryParamsName - Name used to prefix generated signals and methods\n * @param queryParamFactory - Factory function that receives craft context and returns a QueryParamOutput\n * @returns A craft factory function with standalone methods for serializing query params\n *\n * @example\n * Basic usage with craft\n * ```ts\n * const { injectCraft, setPaginationQueryParams } = craft(\n * {\n * providedIn: 'root',\n * name: 'myStore',\n * },\n * craftQueryParam('pagination', () =>\n * queryParam({\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * }, ({set, update, patch, reset}) => ({set, update, patch, reset}))\n * )\n * );\n *\n * // In a component (injection context):\n * const store = injectCraft();\n *\n * // Accessing query param values\n * store.paginationPage(); // Signal<number> for 'page' query param\n * store.paginationPageSize(); // Signal<number> for 'pageSize' query param\n * store.pagination(); // Signal<{ page: number; pageSize: number }>\n *\n * // Updating query param values (also updates URL)\n * store.setPagination({ page: 2, pageSize: 20 });\n * store.updatePagination(current => ({ ...current, page: current.page + 1 }));\n * store.patchPagination({ pageSize: 50 });\n * store.resetPagination();\n * ```\n *\n * @example\n * Using standalone method for navigation outside injection context\n * ```ts\n * // Outside injection context (e.g., in a route resolver, guard, or service method):\n * async navigateToMyPage() {\n * await router.navigate(['my-page'], {\n * queryParams: setPaginationQueryParams({ page: 4, pageSize: 20 }),\n * });\n * }\n *\n * navigateByUrlToMyPage() {\n * router.navigateByUrl(\n * `/my-page?${setPaginationQueryParams({ page: 4, pageSize: 20 })}`\n * );\n * }\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const { injectCraft } = craft(\n * {\n * providedIn: 'root',\n * name: '',\n * },\n * craftQueryParam('pagination', () =>\n * queryParam(\n * {\n * state: {\n * page: { fallbackValue: 1, parse: parseInt, serialize: String },\n * },\n * },\n * ({ state, set }) => ({\n * goToPage: (newPage: number) => {\n * set({ ...state(), page: newPage });\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n * store.goToPagePagination(5); // Custom method from insertion\n * ```\n */\nexport function craftQueryParam<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n const QueryParamsName extends string,\n QueryParamsType,\n Insertions,\n QueryParamsState,\n>(\n queryParamsName: QueryParamsName,\n queryParamFactory: (\n context: CraftFactoryEntries<Context>,\n ) => QueryParamOutput<QueryParamsType, Insertions, QueryParamsState>,\n): CraftQueryParamOutputs<\n Context,\n StoreConfig,\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n> {\n const context = (\n contextData: ContextInput<Context>,\n injector: Injector,\n _storeConfig: StoreConfig,\n _cloudProxy: Context['_cloudProxy'],\n ) => {\n const queryParamState = queryParamFactory(craftFactoryEntries(contextData));\n\n const { props, methods } = Object.entries(queryParamState).reduce(\n (acc, [key, value]) => {\n if (isSignal(value)) {\n (acc.props as Record<string, Signal<any>>)[\n `${queryParamsName}${capitalize(key)}`\n ] = value;\n } else {\n (acc.methods as Record<string, Function>)[\n `${key}${capitalize(queryParamsName)}`\n ] = value;\n }\n return acc;\n },\n { props: {}, methods: {} } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n },\n );\n\n return partialContext({\n props: {\n ...props,\n [`${queryParamsName}`]: queryParamState,\n },\n _queryParams: {\n [`${queryParamsName}`]: {\n config: queryParamState,\n state: queryParamState,\n },\n },\n methods,\n }) as SpecificCraftQueryParamOutputs<\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >;\n };\n\n // when queryParam is called outside the injection context, it will only return the config\n const queryParamsConfig = (\n queryParamFactory({}) as unknown as { _config: QueryParamsType }\n )._config as QueryParamsType;\n\n const setCurrentQueryParams = (\n params: Partial<{\n [K in keyof QueryParamsState]: QueryParamsState[K];\n }>,\n ) =>\n serializeQueryParams(\n params,\n queryParamsConfig as { state: Record<string, QueryParamConfig<unknown>> },\n );\n\n const setCurrentQueryParamsKey = `set${capitalize(\n queryParamsName,\n )}QueryParams`;\n\n return (() =>\n Object.assign(context, {\n [setCurrentQueryParamsKey]: setCurrentQueryParams,\n })) as unknown as CraftQueryParamOutputs<\n Context,\n StoreConfig,\n QueryParamsName,\n QueryParamsType,\n Insertions,\n QueryParamsState\n >;\n}\n\nexport function serializeQueryParams<\n QueryParamsState extends Record<string, unknown>,\n QueryParamsConfig extends {\n state: Record<string, QueryParamConfig<unknown>>;\n },\n>(params: QueryParamsState, queryParamsConfig: QueryParamsConfig) {\n const queryParamsObject = Object.entries(params).reduce(\n (acc, [key, value]) => {\n const paramConfig = queryParamsConfig.state[key];\n if (paramConfig && value !== undefined) {\n acc[key] = paramConfig.serialize(value);\n }\n return acc;\n },\n {} as Record<string, string>,\n );\n\n const result = Object.defineProperty(queryParamsObject, 'toString', {\n value() {\n return serializedQueryParamsObjectToString(this);\n },\n enumerable: false, // 👈 ne s'affichera pas dans les clés\n });\n return result;\n}\n\nexport function serializedQueryParamsObjectToString(\n queryParamsObject: Record<string, unknown>,\n) {\n return Object.entries(queryParamsObject)\n .map(\n ([key, value]) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(value as string)}`,\n )\n .join('&');\n}\n","import { Injector, isSignal, Signal } from '@angular/core';\nimport {\n ContextConstraints,\n ContextInput,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n MergeTwoContexts,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { capitalize } from './util/util';\nimport { QueryParamConfig, QueryParamOutput } from './query-param';\nimport { UnionToTuple } from './util//types/util.type';\nimport {\n serializeQueryParams,\n SpecificCraftQueryParamOutputs,\n} from './craft-query-param';\n\ntype ToSpecificCraftQueryParamsOutputs<\n QueryParamKeysTuple,\n QueryParams,\n Acc extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints\n> = QueryParamKeysTuple extends [infer Head, ...infer Tail]\n ? Head extends keyof QueryParams\n ? QueryParams[Head] extends QueryParamOutput<\n infer QueryParamsType,\n infer Insertions,\n infer QueryParamsState\n >\n ? SpecificCraftQueryParamOutputs<\n Head & string,\n QueryParamsType,\n Insertions,\n QueryParamsState\n > extends infer Current\n ? Current extends ContextConstraints\n ? ToSpecificCraftQueryParamsOutputs<\n Tail,\n QueryParams,\n MergeTwoContexts<Acc, Current>,\n StoreConfig\n >\n : never\n : never\n : PartialContext<{\n _error: {\n message: `Typing Error: QueryParams '${Head &\n string}' value is not a QueryParamsOutput - store: [${StoreConfig['name']}]`;\n };\n }>\n : Acc\n : Acc;\n\nexport type SpecificCraftQueryParamsOutputs<\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>,\n StoreConfig extends StoreConfigConstraints\n> = ToSpecificCraftQueryParamsOutputs<\n UnionToTuple<QueryParamKeys>,\n QueryParams,\n PartialContext<{}>,\n StoreConfig\n>;\n\ntype SpecificCraftQueryStandaloneOutputs<\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>\n> = {\n [K in QueryParamKeys as `set${Capitalize<\n K & string\n >}QueryParam`]: QueryParams[K] extends QueryParamOutput<\n unknown,\n unknown,\n infer QueryParamsState\n >\n ? <\n T extends Partial<{\n [StateKey in keyof QueryParamsState]: QueryParamsState[StateKey];\n }>\n >(\n params: T\n ) => {\n [StateKey in keyof T]: string;\n }\n : never;\n};\n\ntype CraftQueryParamsOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftQueryParamsOutputs<QueryParamKeys, QueryParams, StoreConfig>,\n SpecificCraftQueryStandaloneOutputs<QueryParamKeys, QueryParams>\n>;\n\n/**\n * Creates a craft factory for managing multiple reactive query parameter groups integrated with the craft store.\n *\n * This function allows you to define multiple named query parameter groups within a single craft store by:\n * - Creating typed signals for each query parameter group prefixed with their respective names\n * - Providing standalone methods to serialize query params for navigation outside injection context\n * - Synchronizing all query parameter groups with URL query parameters automatically\n *\n * @remarks\n * **Important:** The `queryParamFactory` function must return an object where each value is a `queryParam()` call.\n * Since `queryParam()` requires an injection context, `craftQueryParams` handles this by:\n * - Calling the factory within an injection context to create the reactive query param managers\n * - Calling the factory outside injection context to extract configurations for standalone methods\n *\n * **Warning:** Be careful to avoid query params key collisions between different groups. (There is no verification yet)\n *\n * @param queryParamFactory - Factory function that receives craft context and returns an object of QueryParamOutput instances\n * @returns A craft factory function with standalone methods for serializing each query param group\n *\n * @example\n * Basic usage with multiple query param groups\n * ```ts\n * const { injectCraft, setPaginationQueryParam, setActiveQueryParam } = craft(\n * {\n * providedIn: 'root',\n * name: 'myStore',\n * },\n * craftQueryParams(() => ({\n * pagination: queryParam({\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (value: string) => parseInt(value, 10),\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * }, ({ set, reset }) => ({ set, reset })),\n * active: queryParam({\n * state: {\n * isActive: {\n * fallbackValue: false,\n * parse: (value: string) => value === 'true',\n * serialize: (value: unknown) => String(value),\n * },\n * },\n * }, ({ set, reset }) => ({ set, reset })),\n * }))\n * );\n *\n * // In a component (injection context):\n * const store = injectCraft();\n *\n * // Accessing query param values\n * store.paginationPage(); // Signal<number> for 'page' from pagination group\n * store.paginationPageSize(); // Signal<number> for 'pageSize' from pagination group\n * store.pagination(); // Signal<{ page: number; pageSize: number }>\n * store.activeIsActive(); // Signal<boolean> for 'isActive' from active group\n * store.active(); // Signal<{ isActive: boolean }>\n *\n * // Updating query param values (also updates URL)\n * store.setPagination({ page: 2, pageSize: 20 });\n * store.setActive({ isActive: true });\n * store.resetPagination();\n * store.resetActive();\n * ```\n *\n * @example\n * Using standalone methods for navigation outside injection context\n * ```ts\n * // Outside injection context (e.g., in a route resolver, guard, or service method):\n * async navigateToMyPage() {\n * await router.navigate(['my-page'], {\n * queryParams: {\n * ...setPaginationQueryParam({ page: 4, pageSize: 20 }),\n * ...setActiveQueryParam({ isActive: true }),\n * },\n * });\n * }\n *\n * navigateByUrlToMyPage() {\n * const paginationParams = setPaginationQueryParam({ page: 4, pageSize: 20 });\n * const activeParams = setActiveQueryParam({ isActive: true });\n * router.navigateByUrl(\n * `/my-page?${paginationParams}&${activeParams}`\n * );\n * }\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const { injectCraft } = craft(\n * {\n * providedIn: 'root',\n * name: 'myStore',\n * },\n * craftQueryParams(() => ({\n * pagination: queryParam(\n * {\n * state: {\n * page: { fallbackValue: 1, parse: parseInt, serialize: String },\n * },\n * },\n * ({ state, set }) => ({\n * goToPage: (newPage: number) => {\n * set({ ...state(), page: newPage });\n * },\n * })\n * ),\n * filters: queryParam({\n * state: {\n * search: { fallbackValue: '', parse: String, serialize: String },\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n * store.goToPagePagination(5); // Custom method from pagination insertion\n * store.filtersSearch(); // Signal<string> for 'search' from filters group\n * ```\n */\nexport function craftQueryParams<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n QueryParamKeys extends keyof QueryParams,\n QueryParams extends Record<QueryParamKeys, unknown>\n>(\n queryParamFactory: (context: CraftFactoryEntries<Context>) => QueryParams\n): CraftQueryParamsOutputs<Context, StoreConfig, QueryParamKeys, QueryParams> {\n const context = (\n contextData: ContextInput<Context>,\n injector: Injector,\n _storeConfig: StoreConfig,\n _cloudProxy: Context['_cloudProxy']\n ) => {\n console.log('contextData', contextData);\n const queryParamStates = queryParamFactory(\n craftFactoryEntries(contextData)\n );\n\n const { props, methods } = Object.entries(queryParamStates).reduce(\n (acc, [key, queryParam]) => {\n const { props, methods } = Object.entries(\n queryParam as QueryParamOutput<unknown, unknown, unknown>\n ).reduce(\n (acc, [queryParamKey, queryParamValue]) => {\n if (isSignal(queryParamValue)) {\n (acc.props as Record<string, Signal<any>>)[\n `${key}${capitalize(queryParamKey)}`\n ] = queryParamValue;\n } else {\n (acc.methods as Record<string, Function>)[\n `${queryParamKey}${capitalize(key)}`\n ] = queryParamValue as Function;\n }\n return acc;\n },\n { props: {}, methods: {} } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n }\n );\n\n Object.assign(acc.props, props);\n Object.assign(acc.methods, methods);\n\n return acc;\n },\n { props: {}, methods: {} } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n }\n );\n\n return partialContext({\n props: { ...props, ...queryParamStates },\n _queryParams: Object.entries(queryParamStates).reduce(\n (acc, [key, queryParam]) => {\n acc[key] = {\n config: queryParam,\n state: queryParam,\n };\n return acc;\n },\n {} as Record<string, { config: unknown; state: unknown }>\n ),\n methods,\n }) as SpecificCraftQueryParamsOutputs<\n QueryParamKeys,\n QueryParams,\n StoreConfig\n >;\n };\n\n // when queryParam is called outside the injection context, it will only return the config\n const queryParamsConfigs = queryParamFactory({});\n\n const setQueryParams = Object.entries(queryParamsConfigs).reduce(\n (acc, [key, queryParam]) => {\n const setCurrentQueryParams = (params: Record<string, unknown>) => {\n return serializeQueryParams(\n params,\n (queryParam as QueryParamOutput<unknown, unknown, unknown>)\n ._config as { state: Record<string, QueryParamConfig<unknown>> }\n );\n };\n const setCurrentQueryParamsKey = `set${capitalize(key)}QueryParam`;\n acc[setCurrentQueryParamsKey] = setCurrentQueryParams;\n return acc;\n },\n {} as Record<string, Function>\n );\n\n return (() =>\n Object.assign(\n context,\n setQueryParams\n )) as unknown as CraftQueryParamsOutputs<\n Context,\n StoreConfig,\n QueryParamKeys,\n QueryParams\n >;\n}\n","import { MergeObject, MergeObjects } from './util/util.type';\nimport {\n ContextConstraints,\n CraftFactoryUtility,\n StoreConfigConstraints,\n PartialContext,\n craftFactoryEntries,\n partialContext,\n} from './craft';\nimport { ResourceByIdRef } from './resource-by-id';\nimport { QueryOutput, QueryRef } from './query';\n\ntype SpecificCraftQueryOutputs<\n ResourceName extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs,\n> = PartialContext<{\n props: {\n [key in `${ResourceName & string}`]: QueryOutput<\n ResourceState,\n ResourceArgsParams,\n ResourceParams,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >;\n };\n _query: {\n [key in ResourceName & string]: QueryOutput<\n ResourceState,\n ResourceArgsParams,\n ResourceParams,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >;\n };\n}>;\n\ntype CraftQueryOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n ResourceName extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftQueryOutputs<\n ResourceName,\n ResourceState,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >\n>;\n\ntype ContextQueryEntries<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n ResourceName extends string,\n> = Context['_inputs'] &\n Context['_injections'] &\n Context['_sources'] &\n Omit<Context['props'], keyof Context['_mutation']> &\n Context['_AsyncProcess'] &\n Context['_mutation'] & {\n INSERT_CONFIG: {\n storeName: StoreConfig['name'];\n key: NoInfer<ResourceName>;\n };\n };\n\n/**\n * Creates a query definition for use within a craft store, enabling reactive data fetching with automatic state management.\n *\n * This function integrates a `query()` instance into a craft store by:\n * - Registering the query under a specific name in the store\n * - Providing automatic execution when params change\n * - Exposing query state signals (value, status, error, isLoading)\n * - Enabling reactive connections to mutations, sources, and other store entries\n * - Supporting insertions for extended functionality (optimistic updates, persistence, etc.)\n * - Providing type-safe access to query results and methods\n *\n * @remarks\n * **Use Cases:**\n * - **Server state management**: Fetch and cache data from APIs\n * - **Automatic refetching**: Re-fetch when params change reactively\n * - **Optimistic updates**: Update UI instantly while mutations execute\n * - **Cache synchronization**: Keep local cache in sync with server state after mutations\n * - **Data persistence**: Cache query results across sessions\n * - **Loading states**: Track and display loading/error states automatically\n *\n * **Context Access:**\n * The query factory receives full access to the craft context:\n * - Sources: React to user events and triggers\n * - Mutations: Coordinate with mutation state and results\n * - Other queries: Derive data from other queries\n * - Injections: Access Angular services and dependencies\n * - INSERT_CONFIG: Store name and query key for insertions\n *\n * **Reactive Patterns:**\n * - Use `insertReactOnMutation()` to synchronize with mutation results\n * - Bind to sources for manual refetch triggers\n * - Use with identifier for parallel query execution\n * - Combine with `preservePreviousValue` to prevent flickering\n *\n * **Store Integration:**\n * - Query accessible as: `store.queryName`\n * - Returns signals: `store.queryName.value()`, `store.queryName.status()`\n * - With identifier: `store.queryName.select(id)` for individual instances\n * - Custom insertions add methods: `store.queryName.customMethod()`\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template ResourceName - The name of the query (must be a literal string)\n * @template ResourceState - The type of the query result data\n * @template ResourceParams - The type of the query parameters\n * @template ResourceArgsParams - The type of method arguments (for method-based queries)\n * @template InsertionsOutputs - The accumulated outputs from query insertions\n * @template IsMethod - Whether the query uses method-based triggering\n * @template SourceParams - The type of source params (for source-based queries)\n * @template GroupIdentifier - The identifier type (for queries with identifier)\n *\n * @param resourceName - The name under which this query will be registered in the store.\n * Used to access the query: `store.resourceName`\n * @param queryFactory - Factory function that receives the craft context and returns a query() instance.\n * Has access to all other craft entries (sources, mutations, queries, states) defined before it.\n *\n * @returns A craft factory utility that integrates the query into the store with:\n * - `store.queryName`: The query instance with all its signals and methods\n * - Full type safety for query state and operations\n *\n * @example\n * Basic query with automatic execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('currentUser', () =>\n * query({\n * params: () => currentUserId(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access query state\n * console.log(store.currentUser.status()); // 'loading'\n * console.log(store.currentUser.value()); // undefined initially\n *\n * // After loading completes\n * console.log(store.currentUser.status()); // 'resolved'\n * console.log(store.currentUser.value()); // { id: '123', name: 'John', ... }\n * console.log(store.currentUser.isLoading()); // false\n * console.log(store.currentUser.hasValue()); // true\n * ```\n *\n * @example\n * Query with optimistic updates from mutations\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateTodo: mutation({\n * method: (todo: Todo) => todo,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('todos', ({ updateTodo }) =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateTodo, {\n * // Update UI instantly while mutation is loading\n * optimisticUpdate: ({ queryResource, mutationParams }) => {\n * const todos = queryResource.value() ?? [];\n * return todos.map(todo =>\n * todo.id === mutationParams.id ? mutationParams : todo\n * );\n * },\n * // Confirm update when mutation resolves\n * update: ({ queryResource, mutationParams }) => {\n * const todos = queryResource.value() ?? [];\n * return todos.map(todo =>\n * todo.id === mutationParams.id ? mutationParams : todo\n * );\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Update a todo - UI updates immediately (optimistic)\n * store.mutateUpdateTodo({ id: '1', text: 'Updated', done: true });\n * // store.todos.value() already reflects the change\n * ```\n *\n * @example\n * Query with patch-based updates\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateEmail: mutation({\n * method: (data: { userId: string; email: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}/email`, {\n * method: 'PATCH',\n * body: JSON.stringify({ email: params.email }),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('user', ({ updateEmail }) =>\n * query(\n * {\n * params: () => currentUserId(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateEmail, {\n * // Patch only the email field\n * optimisticPatch: {\n * email: ({ mutationParams }) => mutationParams.email,\n * },\n * patch: {\n * email: ({ mutationParams }) => mutationParams.email,\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Only email field is updated, rest of user data unchanged\n * store.mutateUpdateEmail({ userId: '123', email: 'new@example.com' });\n * ```\n *\n * @example\n * Query with reload on mutation events\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * createPost: mutation({\n * method: (data: CreatePostData) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * deletePost: mutation({\n * method: (postId: string) => ({ postId }),\n * loader: async ({ params }) => {\n * await fetch(`/api/posts/${params.postId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * }),\n * })),\n * craftQuery('posts', ({ createPost, deletePost }) =>\n * query(\n * {\n * params: () => ({ page: 1 }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts?page=${params.page}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(createPost, {\n * reload: { onMutationResolved: true }, // Reload after create\n * }),\n * insertReactOnMutation(deletePost, {\n * reload: { onMutationResolved: true }, // Reload after delete\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Posts list automatically reloads after create/delete\n * store.mutateCreatePost({ title: 'New Post', content: '...' });\n * // -> posts query reloads automatically when mutation completes\n * ```\n *\n * @example\n * Query with identifier for parallel execution\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('userDetails', () =>\n * query({\n * params: () => selectedUserId(),\n * identifier: (userId) => userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access specific user instances\n * const user1 = store.userDetails.select('user-1');\n * const user2 = store.userDetails.select('user-2');\n *\n * console.log(user1?.status()); // 'resolved'\n * console.log(user1?.value()); // { id: 'user-1', name: '...' }\n * console.log(user2?.status()); // 'loading'\n * ```\n *\n * @example\n * Query with streaming data\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('liveCount', () =>\n * query({\n * params: () => ({}),\n * stream: async () => {\n * const resultSignal = signal({ count: 0 });\n *\n * // Simulate streaming updates\n * const interval = setInterval(() => {\n * resultSignal.update(v => ({ count: v.count + 1 }));\n * }, 1000);\n *\n * return resultSignal;\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Value updates continuously as stream emits\n * console.log(store.liveCount.value()); // { count: 5 }\n * // ... after 1 second\n * console.log(store.liveCount.value()); // { count: 6 }\n * ```\n *\n * @example\n * Query with persistence\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('products', () =>\n * query(\n * {\n * params: () => ({ category: currentCategory() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/products?category=${params.category}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'ProductStore',\n * key: 'products',\n * cacheTime: 600000, // 10 minutes\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Products are cached in localStorage\n * // On next visit, cached data loads instantly while fresh data fetches\n * console.log(store.products.value()); // Cached data available immediately\n * ```\n *\n * @example\n * Query reacting to sources\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * refresh: source<void>(),\n * }),\n * craftQuery('data', ({ refresh }) =>\n * query({\n * method: afterRecomputation(refresh, () => ({})),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Query executes automatically when source emits\n * store.setRefresh();\n * // -> data query executes\n * ```\n *\n * @example\n * Complex coordination with multiple mutations and conditional reloads\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * updateArticle: mutation({\n * method: (data: Article) => data,\n * identifier: (data) => data.id,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/articles/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * })),\n * craftQuery('articles', ({ updateArticle }) =>\n * query(\n * {\n * params: () => ({ status: 'published' }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/articles?status=${params.status}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateArticle, {\n * // Only reload if the update affects published articles\n * reload: {\n * onMutationResolved: ({ mutationParams }) =>\n * mutationParams.status === 'published',\n * },\n * // Patch the article in the list optimistically\n * optimisticUpdate: ({ queryResource, mutationParams }) => {\n * const articles = queryResource.value() ?? [];\n * return articles.map(article =>\n * article.id === mutationParams.id ? mutationParams : article\n * );\n * },\n * })\n * )\n * )\n * );\n * ```\n */\nexport function craftQuery<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n const ResourceName extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n ResourceArgsParams,\n InsertionsOutputs,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n>(\n resourceName: ResourceName,\n queryFactory: (\n context: ContextQueryEntries<Context, StoreConfig, ResourceName>,\n ) => QueryOutput<\n ResourceState,\n ResourceArgsParams,\n ResourceParams,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >,\n): CraftQueryOutputs<\n Context,\n StoreConfig,\n ResourceName,\n NoInfer<ResourceState>,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n> {\n return () => (contextData, injector, storeConfig) => {\n const queryFactoryContext = craftFactoryEntries(contextData);\n const queryRef = queryFactory({\n ...queryFactoryContext,\n INSERT_CONFIG: {\n storeName: storeConfig.name,\n key: resourceName,\n },\n } as ContextQueryEntries<\n Context,\n StoreConfig,\n ResourceName\n >) as unknown as QueryRef<\n ResourceState,\n ResourceParams,\n ResourceArgsParams,\n InsertionsOutputs,\n IsMethod,\n SourceParams,\n GroupIdentifier\n >;\n\n return partialContext({\n props: {\n [`${resourceName as ResourceName}`]: Object.assign(\n queryRef,\n ) as MergeObject<\n ResourceByIdRef<\n GroupIdentifier & string,\n ResourceState,\n ResourceParams\n >,\n InsertionsOutputs\n >,\n },\n _query: {\n [resourceName as ResourceName]: queryRef,\n },\n }) as SpecificCraftQueryOutputs<\n ResourceName,\n ResourceState,\n ResourceParams,\n ResourceArgsParams,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n InsertionsOutputs\n >;\n };\n}\n","import { WritableSignal } from '@angular/core';\nimport {\n ContextConstraints,\n EmptyContext,\n CraftFactoryUtility,\n StoreConfigConstraints,\n partialContext,\n CloudProxySource,\n} from './craft';\nimport { Prettify } from './util/util.type';\nimport { FlatRecord, STORE_CONFIG_TOKEN } from './util/util.type';\nimport { capitalize } from './util/util';\n\ntype InferQueryParamsState<T> = T extends WritableSignal<infer U> ? U : never;\n\ntype SpecificCraftSetAllQueriesParamsStandaloneOutputs<\n Context extends ContextConstraints,\n> = {\n [K in `setAll${Capitalize<\n (typeof STORE_CONFIG_TOKEN)['NAME']\n >}QueryParams`]: <\n AllQueriesParamsState extends {\n [K in keyof Context['_queryParams']]: 'state' extends keyof Context['_queryParams'][K]\n ? InferQueryParamsState<Context['_queryParams'][K]['state']>\n : 'STORE_CONFIG_ERROR: When using craftSetAllQueriesParamsStandalone, each query param configuration must define a state';\n },\n >(\n params: Prettify<AllQueriesParamsState>,\n ) => {\n [K in keyof FlatRecord<AllQueriesParamsState>]: string;\n };\n};\n\ntype CraftSetAllQueriesParamsStandaloneOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n EmptyContext,\n SpecificCraftSetAllQueriesParamsStandaloneOutputs<Context>\n>;\n\n/**\n * Creates a standalone method to set all query parameters at once for use in Angular Router navigation.\n *\n * This function generates a utility method that:\n * - Collects query parameter state from all registered query params in the store\n * - Serializes all values into URL-compatible strings\n * - Returns a flat object compatible with Angular Router's `queryParams` option\n * - Provides a `toString()` method for use with `navigateByUrl()`\n * - Enables type-safe batch updates of all query parameters\n *\n * @remarks\n * **Use Cases:**\n * - **Programmatic navigation**: Set all query params when navigating to a route\n * - **Link generation**: Create URLs with all current query parameter state\n * - **Deep linking**: Generate shareable URLs with complete state\n * - **Bulk updates**: Update multiple query param groups in one operation\n *\n * **Naming Convention:**\n * - Generated method: `setAll{StoreName}QueryParams`\n * - Example: For store named \"MyStore\", method is `setAllMyStoreQueryParams`\n *\n * **Router Integration:**\n * - Use with `router.navigate(['/path'], { queryParams: result })`\n * - Use with `router.navigateByUrl(`/path?${result}`)`\n * - Compatible with `routerLink` directive\n *\n * **Type Safety:**\n * - Input is typed based on all registered query param configurations\n * - Output is a flat record of string values ready for the URL\n * - TypeScript ensures all required query param groups are provided\n *\n * **Requirements:**\n * - Must be used after all `craftQueryParam()` definitions in the craft store\n * - Each query param must define a `state` with parse/serialize/fallbackValue\n *\n * @template Context - The craft store context type containing all query param definitions\n * @template StoreConfig - The craft store configuration type with store name\n *\n * @returns A craft factory utility that adds a standalone method:\n * `setAll{StoreName}QueryParams(params)` - Accepts object with all query param states,\n * returns flat string record for router + toString() method for URL construction\n *\n * @example\n * Basic usage with router.navigate\n * ```ts\n * const { injectCraft, setAllMyStoreQueryParams } = craft(\n * { name: 'MyStore', providedIn: 'root' },\n * craftQueryParam('pagination', () =>\n * queryParam({\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (v) => parseInt(v, 10),\n * serialize: (v) => String(v),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (v) => parseInt(v, 10),\n * serialize: (v) => String(v),\n * },\n * },\n * })\n * ),\n * craftQueryParam('filter', () =>\n * queryParam({\n * state: {\n * search: {\n * fallbackValue: '',\n * parse: (v) => v,\n * serialize: (v) => v,\n * },\n * active: {\n * fallbackValue: false,\n * parse: (v) => v === 'true',\n * serialize: (v) => String(v),\n * },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * // In a component\n * const router = inject(Router);\n *\n * function goToPage(page: number) {\n * router.navigate(['/items'], {\n * queryParams: setAllMyStoreQueryParams({\n * pagination: { page, pageSize: 20 },\n * filter: { search: 'angular', active: true },\n * }),\n * });\n * // URL: /items?page=5&pageSize=20&search=angular&active=true\n * }\n * ```\n *\n * @example\n * Using with navigateByUrl and toString()\n * ```ts\n * const { setAllBlogQueryParams } = craft(\n * { name: 'Blog', providedIn: 'root' },\n * craftQueryParam('sorting', () =>\n * queryParam({\n * state: {\n * sortBy: {\n * fallbackValue: 'date',\n * parse: (v) => v,\n * serialize: (v) => v,\n * },\n * order: {\n * fallbackValue: 'desc' as 'asc' | 'desc',\n * parse: (v) => v as 'asc' | 'desc',\n * serialize: (v) => v,\n * },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * const router = inject(Router);\n *\n * function goToPosts() {\n * const params = setAllBlogQueryParams({\n * sorting: { sortBy: 'title', order: 'asc' },\n * });\n *\n * // Use toString() for navigateByUrl\n * router.navigateByUrl(`/posts?${params}`);\n * // URL: /posts?sortBy=title&order=asc\n * }\n * ```\n *\n * @example\n * Type-safe usage with autocomplete\n * ```ts\n * const { setAllShopQueryParams } = craft(\n * { name: 'Shop', providedIn: 'root' },\n * craftQueryParam('filters', () =>\n * queryParam({\n * state: {\n * category: { fallbackValue: 'all', parse: String, serialize: String },\n * minPrice: { fallbackValue: 0, parse: Number, serialize: String },\n * maxPrice: { fallbackValue: 1000, parse: Number, serialize: String },\n * },\n * })\n * ),\n * craftQueryParam('view', () =>\n * queryParam({\n * state: {\n * layout: { fallbackValue: 'grid', parse: String, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * // TypeScript enforces providing all query param groups\n * const queryParams = setAllShopQueryParams({\n * filters: { category: 'electronics', minPrice: 100, maxPrice: 500 },\n * view: { layout: 'list' },\n * });\n * // ✓ Type-safe: all required groups provided\n *\n * // TypeScript error if missing a group:\n * // const incomplete = setAllShopQueryParams({\n * // filters: { category: 'electronics', minPrice: 100, maxPrice: 500 },\n * // // Error: Property 'view' is missing\n * // });\n * ```\n *\n * @example\n * Generating shareable links\n * ```ts\n * const { injectCraft, setAllArticleQueryParams } = craft(\n * { name: 'Article', providedIn: 'root' },\n * craftQueryParam('reader', () =>\n * queryParam({\n * state: {\n * fontSize: { fallbackValue: 16, parse: Number, serialize: String },\n * theme: { fallbackValue: 'light', parse: String, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * const store = injectCraft();\n *\n * function getShareableLink(): string {\n * const params = setAllArticleQueryParams({\n * reader: {\n * fontSize: store.readerFontSize(),\n * theme: store.readerTheme(),\n * },\n * });\n *\n * return `${window.location.origin}/article/123?${params}`;\n * // Returns: https://example.com/article/123?fontSize=18&theme=dark\n * }\n * ```\n *\n * @example\n * Conditional query param values\n * ```ts\n * const { setAllSearchQueryParams } = craft(\n * { name: 'Search', providedIn: 'root' },\n * craftQueryParam('query', () =>\n * queryParam({\n * state: {\n * q: { fallbackValue: '', parse: String, serialize: String },\n * page: { fallbackValue: 1, parse: Number, serialize: String },\n * },\n * })\n * ),\n * craftQueryParam('advanced', () =>\n * queryParam({\n * state: {\n * dateFrom: { fallbackValue: '', parse: String, serialize: String },\n * dateTo: { fallbackValue: '', parse: String, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * function searchWithFilters(searchTerm: string, useAdvanced: boolean) {\n * const router = inject(Router);\n *\n * router.navigate(['/search'], {\n * queryParams: setAllSearchQueryParams({\n * query: { q: searchTerm, page: 1 },\n * advanced: useAdvanced\n * ? { dateFrom: '2024-01-01', dateTo: '2024-12-31' }\n * : { dateFrom: '', dateTo: '' }, // Use fallback values\n * }),\n * });\n * }\n * ```\n *\n * @example\n * Integration with routerLink directive\n * ```ts\n * // In component class\n * const { setAllProductQueryParams } = craft(\n * { name: 'Product', providedIn: 'root' },\n * craftQueryParam('display', () =>\n * queryParam({\n * state: {\n * view: { fallbackValue: 'grid', parse: String, serialize: String },\n * perPage: { fallbackValue: 12, parse: Number, serialize: String },\n * },\n * })\n * ),\n * craftSetAllQueriesParamsStandalone()\n * );\n *\n * // Generate query params for template\n * listViewParams = setAllProductQueryParams({\n * display: { view: 'list', perPage: 24 },\n * });\n *\n * gridViewParams = setAllProductQueryParams({\n * display: { view: 'grid', perPage: 12 },\n * });\n *\n * // In template\n * // <a [routerLink]=\"['/products']\" [queryParams]=\"listViewParams\">List View</a>\n * // <a [routerLink]=\"['/products']\" [queryParams]=\"gridViewParams\">Grid View</a>\n * ```\n */\nexport function craftSetAllQueriesParamsStandalone<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n>(): CraftSetAllQueriesParamsStandaloneOutputs<Context, StoreConfig> {\n return (_cloudProxy: CloudProxySource, storeConfig) => {\n return Object.assign(() => partialContext({}), {\n [`setAll${capitalize(storeConfig.name)}QueryParams`]: (allQueryParams: {\n [queryParamsName: string]: unknown;\n }) => {\n const { flatParams, queryStringParts } = Object.entries(\n allQueryParams,\n ).reduce(\n (acc, [queryParamsName, params]) => {\n console.log(`Setting query params for ${queryParamsName}:`, params);\n const queryParams = (\n _cloudProxy[\n `set${capitalize(queryParamsName)}QueryParams`\n ] as Function\n )(params as Record<string, unknown>);\n Object.entries(queryParams).forEach(([key, value]) => {\n acc.flatParams[key] = value;\n });\n // Keep the string representation for later\n acc.queryStringParts.push(\n // If queryParams is already something like URLSearchParams-like:\n queryParams.toString(),\n );\n\n return acc;\n },\n {\n flatParams: {} as Record<string, unknown>,\n queryStringParts: [] as string[],\n },\n );\n\n // Define toString only once, after the reduce\n const result = Object.defineProperty(flatParams, 'toString', {\n value() {\n // Join all partial query strings with \"&\"\n return queryStringParts\n .filter((part) => part && part.length > 0)\n .join('&');\n },\n enumerable: false,\n configurable: true,\n writable: true,\n });\n\n return result;\n },\n });\n };\n}\n","import { isSignal } from '@angular/core';\nimport {\n ContextConstraints,\n CraftFactoryUtility,\n PartialContext,\n partialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { SignalSource } from './signal-source';\nimport { Source$ } from './source$';\nimport { capitalize } from './util/util';\n\n// todo handle Observable that are readonly (not Subject...)\n\ntype InferSourceType<S> =\n S extends SignalSource<infer T>\n ? T\n : S extends Source$<infer U>\n ? U\n : S extends _Subscribable<infer V>\n ? V\n : never;\n\ntype PrefixedSourceType<S> =\n S extends SignalSource<infer T>\n ? 'set'\n : S extends Source$<infer U>\n ? 'emit'\n : S extends {\n next: (value: infer V) => void;\n }\n ? 'next'\n : never;\n\nexport type SourceSetterMethods<Sources extends {}> = {\n [K in keyof Sources as `${PrefixedSourceType<Sources[K]>}${Capitalize<string & K>}`]: (\n payload: InferSourceType<Sources[K]>,\n ) => void;\n};\n\ntype SpecificCraftSourcesOutputs<Sources extends {}> = PartialContext<{\n methods: SourceSetterMethods<Sources>;\n _sources: Sources;\n}>;\n\ntype CraftSourcesOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Inputs extends {},\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftSourcesOutputs<Inputs>\n>;\n\n// Help to infer RxJs Observable inner type without referencing the library in the types\ninterface _Subscribable<T> {\n subscribe(observer: (value: T) => void): unknown;\n}\n\n/**\n * Creates source definitions for use within a craft store, enabling reactive signal-source-driven communication.\n *\n * `craftSources` integrates source instances into a craft store by:\n * - Registering multiple sources with their names as keys\n * - Automatically generating setter methods with `set` prefix for each source\n * - Providing type-safe access to sources and their setter methods\n * - Enabling reactive patterns where states and queries can react to source emissions\n *\n * @param sourcesFactory - A factory function that returns an object mapping source names to Source instances.\n * Each source can be a SignalSource, Source$, or any Observable-like object.\n * The factory enables sources to be created within Angular's injection context.\n *\n * @returns A craft factory utility that:\n * - Makes sources accessible in context for other craft entries via `context.sourceName`\n * - Adds prefixed setter methods to the store: `store.setSourceName(payload)`\n *\n * @example\n * ```ts\n * const { injectCraft } = craft(\n * { name: 'MyStore', providedIn: 'root' },\n * craftSources(() => ({\n * userAction: source$<string>(),\n * refresh: source$<void>(),\n * })),\n * );\n *\n * const store = injectCraft();\n * store.setUserAction('clicked');\n * ```\n */\nexport function craftSources<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n Sources extends Record<\n string,\n SignalSource<any> | Source$<any> | _Subscribable<any>\n >,\n>(\n sourcesFactory: () => Sources, // Return a function enable to run source$ in injection context\n): CraftSourcesOutputs<Context, StoreConfig, Sources> {\n return (() => (contextData: ContextConstraints) => {\n const sources = sourcesFactory();\n const methods = Object.entries(sources).reduce(\n (acc, [key, source]) => {\n const prefix = isSignal(source)\n ? 'set'\n : 'emit' in source\n ? 'emit'\n : 'next' in source\n ? 'next'\n : undefined;\n\n if (!prefix) {\n return acc;\n }\n\n return {\n ...acc,\n [`${prefix}${capitalize(key)}`]: (payload: unknown) => {\n if (isSignal(source)) {\n source.set(payload);\n } else if ('emit' in source) {\n source.emit(payload);\n } else if ('next' in source) {\n //@ts-expect-error next exists on both Subject and EventEmitter but with different types, we need to check which one it is\n source.next(payload);\n }\n },\n };\n },\n {} as Record<string, (payload: unknown) => void>,\n );\n return partialContext({\n _sources: sources,\n methods,\n }) as SpecificCraftSourcesOutputs<Sources>;\n }) as unknown as CraftSourcesOutputs<Context, StoreConfig, Sources>;\n}\n","import {\n ContextConstraints,\n craftFactoryEntries,\n CraftFactoryEntries,\n CraftFactoryUtility,\n partialContext,\n PartialContext,\n StoreConfigConstraints,\n} from './craft';\nimport { StateOutput } from './state';\nimport { isSignal, Signal } from '@angular/core';\nimport { capitalize } from './util/util';\nimport { DeferredExtract } from './util/util.type';\n\ntype SpecificCraftStateOutputs<StateName extends string, State, Insertions> =\n DeferredExtract<Insertions> extends infer Extracted\n ? Extracted extends { props: unknown; methods: Record<string, Function> }\n ? PartialContext<{\n props: {\n [key in StateName]: Signal<State>;\n } & {\n [key in keyof Extracted['props'] as `${StateName &\n string}${Capitalize<key & string>}`]: Extracted['props'][key];\n };\n methods: {\n [key in keyof Extracted['methods'] as `${StateName &\n string}${Capitalize<key & string>}`]: Extracted['methods'][key];\n };\n }>\n : never\n : never;\n\ntype CraftStateOutputs<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n StateName extends string,\n State,\n Insertions,\n> = CraftFactoryUtility<\n Context,\n StoreConfig,\n SpecificCraftStateOutputs<StateName, State, Insertions>\n>;\n\n/**\n * Creates a state definition for use within a craft store, enabling reactive state management with optional custom methods and computed values.\n *\n * This function integrates a `state()` instance into a craft store by:\n * - Registering the state under a specific name in the store\n * - Automatically prefixing custom methods and computed values with the state name\n * - Providing type-safe access to state, methods, and computed properties\n * - Enabling reactive connections to sources, inputs, and other store states\n * - Supporting insertions for extended functionality\n *\n * @remarks\n * **Naming Convention:**\n * - The state is accessible as `store.stateName` (returns the Signal)\n * - Custom methods are prefixed: `store.stateNameMethodName`\n * - Computed values are prefixed: `store.stateNameComputedName`\n *\n * **Use Cases:**\n * - **Local UI state**: Form values, filters, pagination, modal visibility\n * - **Derived state**: Computed values based on state changes\n * - **Coordinated state**: State that reacts to other states or sources\n * - **Encapsulated logic**: State with associated behavior methods\n *\n * **Integration:**\n * - Access to other craft entries (sources, queries, mutations) via context\n * - Can react to sources using `afterRecomputation()`\n * - Supports all state() insertion features (persistence, validation, etc.)\n *\n * @template Context - The craft store context type\n * @template StoreConfig - The craft store configuration type\n * @template StateName - The name of the state (must be a literal string)\n * @template State - The type of the state value\n * @template Insertions - The accumulated outputs from state insertions\n *\n * @param stateName - The name under which this state will be registered in the store.\n * Used as prefix for all methods and computed values.\n * @param stateFactory - Factory function that receives the craft context and returns a state() instance.\n * Has access to all other craft entries (sources, queries, mutations, states) defined before it.\n *\n * @returns A craft factory utility that integrates the state into the store with:\n * - `store.stateName`: Signal returning the current state value\n * - `store.stateNameMethodName`: Prefixed custom methods from insertions\n * - `store.stateNameComputedName`: Prefixed computed signals from insertions\n *\n * @example\n * Basic state without methods\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('counter', () => state(0))\n * );\n *\n * const store = injectCraft();\n *\n * // Access the state\n * console.log(store.counter()); // 0\n *\n * // Update the state\n * store.counter.set(5);\n * console.log(store.counter()); // 5\n * ```\n *\n * @example\n * State with custom methods\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('todos', () =>\n * state(\n * [] as Todo[],\n * ({ state, set }) => ({\n * add: (todo: Todo) => {\n * set([...state(), todo]);\n * },\n * remove: (id: string) => {\n * set(state().filter(t => t.id !== id));\n * },\n * clear: () => {\n * set([]);\n * },\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Use prefixed methods\n * store.todosAdd({ id: '1', text: 'Buy milk', done: false });\n * store.todosAdd({ id: '2', text: 'Walk dog', done: false });\n * console.log(store.todos().length); // 2\n *\n * store.todosRemove('1');\n * console.log(store.todos().length); // 1\n *\n * store.todosClear();\n * console.log(store.todos().length); // 0\n * ```\n *\n * @example\n * State with computed values\n * ```ts\n * const { injectCraft } = craft(\n * { name: 'CartStore', providedIn: 'root' },\n * craftState('items', () =>\n * state(\n * [] as CartItem[],\n * ({ state, set }) => ({\n * add: (item: CartItem) => {\n * set([...state(), item]);\n * },\n * // Computed values are also prefixed\n * count: computed(() => state().length),\n * total: computed(() =>\n * state().reduce((sum, item) => sum + item.price * item.quantity, 0)\n * ),\n * isEmpty: computed(() => state().length === 0),\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access computed values with prefixed names\n * console.log(store.itemsCount()); // 0\n * console.log(store.itemsIsEmpty()); // true\n *\n * store.itemsAdd({ id: '1', name: 'Book', price: 15, quantity: 2 });\n * console.log(store.itemsCount()); // 1\n * console.log(store.itemsTotal()); // 30\n * console.log(store.itemsIsEmpty()); // false\n * ```\n *\n * @example\n * State reacting to sources\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * resetFilters: source<void>(),\n * }),\n * craftState('filters', ({ resetFilters }) =>\n * state(\n * { search: '', category: 'all', priceRange: [0, 1000] },\n * ({ state, set }) => ({\n * setSearch: (search: string) => {\n * set({ ...state(), search });\n * },\n * setCategory: (category: string) => {\n * set({ ...state(), category });\n * },\n * // React to source to reset state\n * reset: afterRecomputation(resetFilters, () => {\n * set({ search: '', category: 'all', priceRange: [0, 1000] });\n * }),\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Use the state\n * store.filtersSetSearch('laptop');\n * store.filtersSetCategory('electronics');\n * console.log(store.filters()); // { search: 'laptop', category: 'electronics', ... }\n *\n * // Reset via source\n * store.setResetFilters();\n * console.log(store.filters()); // { search: '', category: 'all', ... }\n * ```\n *\n * @example\n * State coordinating with multiple sources\n * ```ts\n * const globalReset = source<string>();\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * localReset: source<string>(),\n * }),\n * craftState('pageState', ({ localReset }) =>\n * state(\n * { page: 1, items: [] as string[] },\n * ({ state, set }) => ({\n * addItem: (item: string) => {\n * set({ ...state(), items: [...state().items, item] });\n * },\n * nextPage: () => {\n * set({ ...state(), page: state().page + 1 });\n * },\n * // React to local source\n * localReset: afterRecomputation(localReset, (reason) => {\n * console.log('Local reset:', reason);\n * set({ page: 1, items: [] });\n * }),\n * // React to global source\n * globalReset: afterRecomputation(globalReset, (reason) => {\n * console.log('Global reset:', reason);\n * set({ page: 1, items: ['default'] });\n * }),\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * store.pageStateAddItem('item1');\n * store.pageStateAddItem('item2');\n * console.log(store.pageState().items); // ['item1', 'item2']\n *\n * store.setLocalReset('User action');\n * console.log(store.pageState().items); // []\n *\n * globalReset.set('System reset');\n * console.log(store.pageState().items); // ['default']\n * ```\n *\n * @example\n * State with persistence\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('preferences', () =>\n * state(\n * { theme: 'light', language: 'en', notifications: true },\n * insertLocalStoragePersister({\n * storeName: 'SettingsStore',\n * key: 'preferences',\n * cacheTime: Number.POSITIVE_INFINITY, // Never expire\n * })\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Preferences are automatically persisted and restored\n * store.preferences.set({ theme: 'dark', language: 'fr', notifications: false });\n * // On next app load, preferences are automatically restored\n * ```\n *\n * @example\n * Multiple states in one store\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('ui', () =>\n * state({ sidebarOpen: false, modalOpen: false })\n * ),\n * craftState('user', () =>\n * state({ isAuthenticated: false, userId: null as string | null })\n * ),\n * craftState('notifications', () =>\n * state([] as Notification[])\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Access different states\n * console.log(store.ui()); // { sidebarOpen: false, modalOpen: false }\n * console.log(store.user()); // { isAuthenticated: false, userId: null }\n * console.log(store.notifications()); // []\n *\n * // Update independently\n * store.ui.set({ sidebarOpen: true, modalOpen: false });\n * store.user.set({ isAuthenticated: true, userId: 'user-123' });\n * ```\n */\nexport function craftState<\n Context extends ContextConstraints,\n StoreConfig extends StoreConfigConstraints,\n const StateName extends string,\n State,\n Insertions,\n>(\n stateName: StateName,\n stateFactory: (\n context: CraftFactoryEntries<Context>,\n ) => StateOutput<State, Insertions>,\n): CraftStateOutputs<Context, StoreConfig, StateName, State, Insertions> {\n return () => (contextData) => {\n const stateResult = stateFactory(craftFactoryEntries(contextData));\n\n const { props, methods } = Object.entries(stateResult).reduce(\n (acc, [key, value]) => {\n if (isSignal(value)) {\n (acc.props as Record<string, Signal<any>>)[\n `${stateName}${capitalize(key)}`\n ] = value;\n } else {\n (acc.methods as Record<string, Function>)[\n `${stateName}${capitalize(key)}`\n ] = value;\n }\n return acc;\n },\n {\n props: {},\n methods: {},\n } as {\n props: Record<string, Signal<any>>;\n methods: Record<string, Function>;\n },\n );\n return partialContext({\n props: { [stateName]: stateResult, ...props },\n methods,\n }) as unknown as SpecificCraftStateOutputs<StateName, State, Insertions>;\n };\n}\n","// Not optimized for performance\nexport function isEqual<T>(a: T, b: T): boolean {\n return replaceEqualDeep(a, b) === a;\n}\n\n// Copied From https://github.dev/TanStack/query\n/**\n * This function returns `a` if `b` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between JSON values for example.\n */\nexport function replaceEqualDeep<T>(a: unknown, b: T): T;\nexport function replaceEqualDeep(a: any, b: any): any {\n if (a === b) {\n return a;\n }\n\n const array = isPlainArray(a) && isPlainArray(b);\n\n if (array || (isPlainObject(a) && isPlainObject(b))) {\n const aItems = array ? a : Object.keys(a);\n const aSize = aItems.length;\n const bItems = array ? b : Object.keys(b);\n const bSize = bItems.length;\n const copy: any = array ? [] : {};\n const aItemsSet = new Set(aItems);\n\n let equalItems = 0;\n\n for (let i = 0; i < bSize; i++) {\n const key = array ? i : bItems[i];\n if (\n ((!array && aItemsSet.has(key)) || array) &&\n a[key] === undefined &&\n b[key] === undefined\n ) {\n copy[key] = undefined;\n equalItems++;\n } else {\n copy[key] = replaceEqualDeep(a[key], b[key]);\n if (copy[key] === a[key] && a[key] !== undefined) {\n equalItems++;\n }\n }\n }\n\n return aSize === bSize && equalItems === aSize ? a : copy;\n }\n\n return b;\n}\n\nfunction isPlainArray(value: unknown) {\n return Array.isArray(value) && value.length === Object.keys(value).length;\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\n// eslint-disable-next-line @typescript-eslint/no-wrapper-object-types\nfunction isPlainObject(o: any): o is Object {\n if (!hasObjectPrototype(o)) {\n return false;\n }\n\n // If has no constructor\n const ctor = o.constructor;\n if (ctor === undefined) {\n return true;\n }\n\n // If has modified prototype\n const prot = ctor.prototype;\n if (!hasObjectPrototype(prot)) {\n return false;\n }\n\n // If constructor does not have an Object-specific method\n\n // eslint-disable-next-line no-prototype-builtins\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false;\n }\n\n // Handles Objects created by Object.create(<arbitrary prototype>)\n if (Object.getPrototypeOf(o) !== Object.prototype) {\n return false;\n }\n\n // Most likely a plain Object\n return true;\n}\n\nfunction hasObjectPrototype(o: any): boolean {\n return Object.prototype.toString.call(o) === '[object Object]';\n}\n","import {\n CreateEffectOptions,\n EffectCleanupRegisterFn,\n EffectRef,\n effect,\n untracked,\n} from '@angular/core';\n// from https://github.com/ngxtension/ngxtension-platform\n\n/**\n * We want to have the Tuple in order to use the types in the function signature\n */\nexport type ExplicitEffectValues<T> = {\n [K in keyof T]: () => T[K];\n};\n\n/**\n * Extend the regular set of effect options\n */\ndeclare interface CreateExplicitEffectOptions extends CreateEffectOptions {\n /**\n * Option that allows the computation not to execute immediately, but only run on first change.\n */\n defer?: boolean;\n}\n\n/**\n * This explicit effect function will take the dependencies and the function to run when the dependencies change.\n *\n * @example\n * ```typescript\n * import { explicitEffect } from 'ngxtension/explicit-effect';\n *\n * const count = signal(0);\n * const state = signal('idle');\n *\n * explicitEffect([count, state], ([count, state], cleanup) => {\n * console.log('count updated', count, state);\n *\n * cleanup(() => {\n * console.log('cleanup');\n * });\n * });\n * ```\n *\n * @param deps - The dependencies that the effect will run on\n * @param fn - The function to run when the dependencies change\n * @param options - The options for the effect with the addition of defer (it allows the computation to run on first change, not immediately)\n */\nexport function explicitEffect<\n Input extends readonly unknown[],\n Params = Input,\n>(\n deps: readonly [...ExplicitEffectValues<Input>],\n fn: (deps: Params, onCleanup: EffectCleanupRegisterFn) => void,\n options?: CreateExplicitEffectOptions | undefined,\n): EffectRef {\n let defer = options && options.defer;\n return effect((onCleanup) => {\n const depValues = deps.map((s) => s());\n untracked(() => {\n if (!defer) {\n fn(depValues as any, onCleanup);\n }\n defer = false;\n });\n }, options);\n}\n","import {\n effect,\n EffectCleanupRegisterFn,\n EffectRef,\n InjectionToken,\n Injector,\n} from '@angular/core';\nimport { explicitEffect, ExplicitEffectValues } from '../explicit-effect';\n\nexport const DYNAMIC_EFFECT_REF_INSTANCE_TOKEN = new InjectionToken<EffectRef>(\n 'Injection token used to provide a dynamically created effectRef instance.',\n);\n\nexport function nestedEffect<T, R, GroupIdentifier extends string>(\n parentInjector: Injector,\n effectFn: (onCleanup: EffectCleanupRegisterFn) => void,\n) {\n const injector = Injector.create({\n providers: [\n {\n provide: DYNAMIC_EFFECT_REF_INSTANCE_TOKEN,\n useFactory: () => {\n return effect(effectFn, {\n injector: parentInjector,\n });\n },\n },\n ],\n parent: parentInjector,\n });\n const effectRef = injector.get(DYNAMIC_EFFECT_REF_INSTANCE_TOKEN);\n return effectRef;\n}\n\nexport function explicitNestedEffect<\n T,\n R,\n GroupIdentifier extends string,\n Input extends readonly unknown[],\n Params = Input,\n>(\n parentInjector: Injector,\n deps: readonly [...ExplicitEffectValues<Input>],\n fn: (deps: Params, onCleanup: EffectCleanupRegisterFn) => void,\n) {\n const injector = Injector.create({\n providers: [\n {\n provide: DYNAMIC_EFFECT_REF_INSTANCE_TOKEN,\n useFactory: () => {\n return explicitEffect(deps, fn, {\n injector: parentInjector,\n });\n },\n },\n ],\n parent: parentInjector,\n });\n const effectRef = injector.get(DYNAMIC_EFFECT_REF_INSTANCE_TOKEN);\n return effectRef;\n}\n","import {\n effect,\n inject,\n Injector,\n linkedSignal,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { isEqual } from './util/persister.util';\nimport {\n PersistedQuery,\n PersistedQueryById,\n QueriesPersister,\n} from './util/persister.type';\nimport { nestedEffect } from './util/types/util';\nimport { ResourceByIdRef } from './resource-by-id';\n\nexport function localStoragePersister(prefix: string): QueriesPersister {\n const _injector = inject(Injector);\n const queriesMap = signal(\n new Map<string, PersistedQuery & { storageKey: string }>(),\n {\n equal: () => false,\n }\n );\n\n const queriesByIdMap = signal(\n new Map<string, PersistedQueryById & { storageKey: string }>(),\n {\n equal: () => false,\n }\n );\n\n const newQueryKeysForNestedEffect = linkedSignal<\n any,\n { newKeys: string[] } | undefined\n >({\n source: queriesMap,\n computation: (currentSource, previous) => {\n if (!currentSource || !Array.from(currentSource.keys()).length) {\n return undefined;\n }\n\n const currentKeys = Array.from(currentSource.keys());\n const previousKeys = Array.from(previous?.source?.keys() || []);\n // Find keys that exist in current but not in previous\n const newKeys = currentKeys.filter(\n (key) => !previousKeys.includes(key)\n ) as string[];\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n });\n\n effect(() => {\n if (!newQueryKeysForNestedEffect()?.newKeys) {\n return;\n }\n\n newQueryKeysForNestedEffect()?.newKeys.forEach((newKey) => {\n const data = untracked(() => queriesMap().get(newKey));\n nestedEffect(_injector, () => {\n if (!data) {\n return;\n }\n const { queryResource, queryResourceParamsSrc, storageKey } = data;\n const queryStatus = queryResource.status();\n const queryValue = queryResource.value(); // also track the query value, because the status can stayed local but the value may change\n\n if (queryStatus !== 'resolved' && queryStatus !== 'local') {\n return;\n }\n untracked(() => {\n const queryParams = queryResourceParamsSrc();\n localStorage.setItem(\n storageKey,\n JSON.stringify({\n queryParams,\n queryValue,\n timestamp: Date.now(),\n })\n );\n });\n });\n\n if (data?.waitForParamsSrcToBeEqualToPreviousValue) {\n const waitForParamsSrcToBeEqualToPreviousValueEffect = nestedEffect(\n _injector,\n () => {\n const { queryResourceParamsSrc, storageKey, queryResource } = data;\n const params = queryResourceParamsSrc();\n if (params === undefined) {\n return;\n }\n const storedValue = localStorage.getItem(storageKey);\n if (!storedValue) {\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n try {\n const { queryValue, queryParams, timestamp } =\n JSON.parse(storedValue);\n\n // Check if cache is expired\n if (\n timestamp &&\n data.cacheTime > 0 &&\n isValueExpired(timestamp, data.cacheTime)\n ) {\n localStorage.removeItem(storageKey);\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n\n const isEqualParams = isEqual(params, queryParams);\n if (!isEqualParams) {\n localStorage.removeItem(storageKey);\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n if (isEqualParams) {\n queryResource.set(queryValue);\n }\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n waitForParamsSrcToBeEqualToPreviousValueEffect.destroy();\n return;\n }\n }\n );\n }\n });\n });\n\n const newQueryByIdKeysForNestedEffect = linkedSignal<\n any,\n { newKeys: string[] } | undefined\n >({\n source: queriesByIdMap,\n computation: (currentSource, previous) => {\n if (!currentSource || !Array.from(currentSource.keys()).length) {\n return undefined;\n }\n\n const currentKeys = Array.from(currentSource.keys());\n const previousKeys = Array.from(previous?.source?.keys() || []);\n const newKeys = currentKeys.filter(\n (key) => !previousKeys.includes(key)\n ) as string[];\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n });\n\n effect(() => {\n if (!newQueryByIdKeysForNestedEffect()?.newKeys) {\n return;\n }\n\n // Each time their is a status change in the queryById resource it will save the query with only the resource that are 'resolved' or 'local' (it may be improved)\n newQueryByIdKeysForNestedEffect()?.newKeys.forEach((newKey) => {\n const data = untracked(() => queriesByIdMap().get(newKey));\n nestedEffect(_injector, () => {\n if (!data) {\n return;\n }\n\n const { queryByIdResource, queryResourceParamsSrc, storageKey } = data;\n\n const newRecordInQueryByIdForNestedEffect = linkedSignal<\n any,\n { newKeys: string[] } | undefined\n >({\n source: queryByIdResource,\n computation: (\n currentSource: ReturnType<\n ResourceByIdRef<string, unknown, unknown>\n >,\n previous\n ) => {\n if (!currentSource || !Object.keys(currentSource).length) {\n return undefined;\n }\n\n const currentKeys = Object.keys(currentSource);\n const previousKeys = Array.from(previous?.source?.keys() || []);\n const newKeys = currentKeys.filter(\n (key) => !previousKeys.includes(key)\n ) as string[];\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n });\n newRecordInQueryByIdForNestedEffect()?.newKeys.forEach((newRecord) => {\n const data = untracked(() => queryByIdResource()[newRecord]);\n nestedEffect(_injector, () => {\n if (!data) {\n return;\n }\n\n let storedValue: QueryByIdStored | undefined;\n try {\n storedValue = JSON.parse(\n localStorage.getItem(storageKey) || 'null'\n );\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n localStorage.removeItem(storageKey);\n }\n storedValue = storedValue ?? {\n queryParams: queryResourceParamsSrc(),\n queryByIdValue: {},\n timestamp: Date.now(),\n };\n\n const isStable =\n data.status() === 'resolved' || data.status() === 'local';\n const dataValue = data.hasValue() ? data.value() : undefined;\n untracked(() => {\n storedValue = {\n queryParams: queryResourceParamsSrc(),\n queryByIdValue: {\n ...storedValue?.queryByIdValue,\n [newRecord]: {\n params:\n storedValue?.queryByIdValue[newRecord]?.params ??\n queryResourceParamsSrc(),\n value: dataValue,\n reloadOnMount: !isStable,\n timestamp: Date.now(),\n },\n },\n timestamp: Date.now(),\n };\n localStorage.setItem(storageKey, JSON.stringify(storedValue));\n });\n });\n });\n });\n });\n });\n\n return {\n addQueryToPersist(data: PersistedQuery): void {\n const {\n key,\n queryResource,\n queryResourceParamsSrc,\n waitForParamsSrcToBeEqualToPreviousValue,\n cacheTime,\n } = data;\n\n const storageKey = getStorageKey(prefix, key, 'resource');\n const storedValue = localStorage.getItem(storageKey);\n if (storedValue && !waitForParamsSrcToBeEqualToPreviousValue) {\n try {\n const { queryValue, timestamp } = JSON.parse(storedValue);\n if (\n timestamp &&\n cacheTime > 0 &&\n isValueExpired(timestamp, cacheTime)\n ) {\n localStorage.removeItem(storageKey);\n } else {\n queryResource.set(queryValue);\n }\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n localStorage.removeItem(storageKey);\n }\n }\n queriesMap.update((map) => {\n map.set(key, {\n queryResource,\n queryResourceParamsSrc,\n storageKey,\n waitForParamsSrcToBeEqualToPreviousValue,\n cacheTime,\n key,\n });\n return map;\n });\n },\n\n addQueryByIdToPersist(data: PersistedQueryById): void {\n const { key, queryByIdResource, queryResourceParamsSrc, cacheTime } =\n data;\n\n const storageKey = getStorageKey(prefix, key, 'resourceById');\n let storedValue: QueryByIdStored | undefined;\n try {\n storedValue = JSON.parse(localStorage.getItem(storageKey) || 'null');\n } catch (e) {\n console.error('Error parsing stored value from localStorage', e);\n localStorage.removeItem(storageKey);\n }\n\n const storedValueWithValidCacheTime =\n removeNotValidRecordsWithValidCacheTime(\n storageKey,\n storedValue,\n cacheTime\n );\n if (storedValueWithValidCacheTime) {\n const { queryByIdValue } = storedValueWithValidCacheTime;\n\n if (queryByIdValue && typeof queryByIdValue === 'object') {\n Object.entries(queryByIdValue).forEach(\n ([resourceKey, resourceValue]) => {\n const resourceRef = queryByIdResource.addById(resourceKey, {\n defaultParam: resourceValue.params,\n defaultValue: resourceValue.value,\n });\n // The reload strategy can be improved to prioritize the current displayed resource\n if (resourceValue.reloadOnMount) {\n resourceRef.reload();\n }\n }\n );\n }\n }\n queriesByIdMap.update((map) => {\n map.set(key, {\n queryByIdResource,\n queryResourceParamsSrc,\n storageKey,\n cacheTime,\n key,\n });\n return map;\n });\n },\n\n clearQuery(queryKey: string): void {\n queriesMap.update((map) => {\n map.delete(queryKey);\n localStorage.removeItem(getStorageKey(prefix, queryKey, 'resource'));\n return map;\n });\n },\n\n clearQueryBy(queryByIdKey: string): void {\n queriesByIdMap.update((map) => {\n map.delete(queryByIdKey);\n localStorage.removeItem(\n getStorageKey(prefix, queryByIdKey, 'resourceById')\n );\n return map;\n });\n },\n\n clearAllQueries(): void {\n queriesMap().forEach((_, key) => {\n localStorage.removeItem(getStorageKey(prefix, key, 'resource'));\n });\n queriesMap.update((map) => {\n map.clear();\n return map;\n });\n },\n\n clearAllQueriesById(): void {\n queriesByIdMap().forEach((_, key) => {\n localStorage.removeItem(getStorageKey(prefix, key, 'resourceById'));\n });\n queriesByIdMap.update((map) => {\n map.clear();\n return map;\n });\n },\n clearAllCache(): void {\n this.clearAllQueriesById();\n this.clearAllQueries();\n },\n };\n}\n\ntype QueryByIdStored = {\n queryParams: any;\n queryByIdValue: Record<\n string,\n {\n params: any;\n value: any;\n /**\n * Use it when the resource was loading and didn't finish before the app was closed\n */\n reloadOnMount: boolean;\n timestamp: number;\n }\n >;\n /**\n * Newest timestamp of the stored value\n */\n timestamp: number;\n};\n\nfunction getStorageKey(prefix: string, key: string, type: string) {\n return `ng-craft-${prefix}-${type}-${key}`;\n}\n\nfunction isValueExpired(timestamp: number, cacheTime: number): boolean {\n return Date.now() - timestamp > cacheTime;\n}\n\nfunction removeNotValidRecordsWithValidCacheTime(\n storageKey: string,\n storedValue: QueryByIdStored | undefined,\n cacheTime: number\n): QueryByIdStored | undefined {\n if (!storedValue) {\n return undefined;\n }\n const { queryByIdValue, timestamp } = storedValue;\n\n if (timestamp && cacheTime > 0 && isValueExpired(timestamp, cacheTime)) {\n // remove from storage\n localStorage.removeItem(storageKey);\n return undefined;\n }\n\n const validQueryByIdValue = Object.entries(queryByIdValue).reduce(\n (acc, [key, value]) => {\n const isValueExpiredResult = isValueExpired(value.timestamp, cacheTime);\n if (!isValueExpiredResult) {\n acc[key] = value;\n }\n return acc;\n },\n {} as QueryByIdStored['queryByIdValue']\n );\n\n // update local storage\n localStorage.setItem(\n storageKey,\n JSON.stringify({\n ...storedValue,\n queryByIdValue: validQueryByIdValue,\n })\n );\n\n return {\n ...storedValue,\n queryByIdValue: validQueryByIdValue,\n };\n}\n","import { localStoragePersister } from './local-storage-persister';\nimport {\n InsertionByIdParams,\n InsertionResourceFactoryContext,\n InsertionParams,\n InsertionStateFactoryContext,\n} from './query.core';\nimport { ResourceByIdRef } from './resource-by-id';\nimport { ResourceRef } from '@angular/core';\n\n/**\n * Creates an insertion function that persists resource or state data to localStorage with automatic cache management.\n *\n * This insertion enables automatic persistence and restoration of data across browser sessions, providing:\n * - Automatic saving of query/mutation/state data to localStorage\n * - Restoration of cached data when the application loads\n * - Cache expiration with configurable time-to-live (TTL)\n * - Automatic garbage collection of expired cache entries\n * - Support for both single resources and resources grouped by identifier\n * - Optional waiting for params to stabilize before persisting\n *\n * @remarks\n * **Use Cases:**\n * - **Offline-first applications**: Keep data available when the user goes offline\n * - **Performance optimization**: Show cached data instantly while fetching fresh data\n * - **User experience**: Preserve user's view state across page refreshes\n * - **Reduce server load**: Serve data from cache when it's still fresh\n *\n * **Cache Management:**\n * - Data is stored with a timestamp in localStorage\n * - Expired entries are automatically removed during garbage collection\n * - Each store maintains its own namespace to avoid key collisions\n * - Supports both primitive and complex object serialization\n *\n * **Compatibility:**\n * Works with: `query()`, `mutation()`, `AsyncProcess()`, and `state()`\n *\n * @template GroupIdentifier - The type of identifier for grouped resources (string)\n * @template ResourceState - The type of the resource state (object or undefined)\n * @template ResourceParams - The type of the resource parameters\n * @template PreviousInsertionsOutputs - The accumulated outputs from previous insertions\n * @template StateType - The type of the state (for state() usage)\n * @template CacheTime - The cache time in milliseconds (defaults to 300000 = 5 minutes)\n *\n * @param config - Configuration object:\n * - `storeName`: Prefix for localStorage keys to namespace this store\n * - `key`: Specific key to identify this data within the store\n * - `waitForParamsSrcToBeEqualToPreviousValue` (optional): If true, waits for params to stabilize before persisting.\n * Useful when params can be undefined initially. Default: true\n * - `cacheTime` (optional): Time in milliseconds before cached data is considered stale. Default: 300000 (5 minutes)\n *\n * @returns An insertion function that adds a `persister` property to the resource/state, enabling manual control if needed\n *\n * @example\n * Basic query with localStorage persistence\n * ```ts\n * const userQuery = query(\n * {\n * params: () => ({ userId: currentUserId() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'currentUser',\n * cacheTime: 600000, // 10 minutes\n * })\n * );\n *\n * // On first load, data is fetched from server and cached\n * // On subsequent loads, cached data is shown immediately while fresh data loads in background\n * console.log(userQuery.value()); // Cached data available instantly\n * ```\n *\n * @example\n * Query with identifier for multiple cached instances\n * ```ts\n * const postsQuery = query(\n * {\n * params: () => currentPostId(),\n * identifier: (postId) => postId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts/${params}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'blogApp',\n * key: 'posts',\n * cacheTime: 900000, // 15 minutes\n * })\n * );\n *\n * // Each post is cached individually by its identifier\n * // Cache keys: blogApp:posts:post-123, blogApp:posts:post-456, etc.\n * const post1 = postsQuery.select('post-123');\n * const post2 = postsQuery.select('post-456');\n * ```\n *\n * @example\n * Mutation with persistence for optimistic updates\n * ```ts\n * const updateSettingsMutation = mutation(\n * {\n * method: (settings: UserSettings) => settings,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/settings', {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'userSettings',\n * cacheTime: 86400000, // 24 hours\n * })\n * );\n *\n * // Settings are persisted across sessions\n * // User's preferences survive page refreshes and browser restarts\n * ```\n *\n * @example\n * State persistence for UI preferences\n * ```ts\n * const themeState = state(\n * { mode: 'light', fontSize: 14 } as const,\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'theme',\n * cacheTime: Number.POSITIVE_INFINITY, // Never expire\n * })\n * );\n *\n * // Theme preferences are automatically saved and restored\n * themeState.set({ mode: 'dark', fontSize: 16 });\n * // On next visit, the dark theme is automatically applied\n * ```\n *\n * @example\n * Short-lived cache for frequently changing data\n * ```ts\n * const searchResultsQuery = query(\n * {\n * params: () => ({ query: searchTerm() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/search?q=${params.query}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'searchApp',\n * key: 'results',\n * cacheTime: 60000, // 1 minute - short cache for fresh results\n * })\n * );\n *\n * // Search results are cached briefly to improve UX during navigation\n * // Old results are quickly expired to avoid showing stale data\n * ```\n *\n * @example\n * Waiting for params to stabilize\n * ```ts\n * const userIdSignal = signal<string | undefined>(undefined);\n *\n * const userQuery = query(\n * {\n * params: () => userIdSignal(),\n * loader: async ({ params }) => {\n * if (!params) return undefined;\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'user',\n * waitForParamsSrcToBeEqualToPreviousValue: true, // Wait for userId to be set\n * })\n * );\n *\n * // Persistence waits until userIdSignal has a stable value\n * // Prevents caching with undefined params\n * setTimeout(() => userIdSignal.set('user-123'), 100);\n * ```\n *\n * @example\n * Manual cache control via persister\n * ```ts\n * const dataQuery = query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * },\n * insertLocalStoragePersister({\n * storeName: 'myApp',\n * key: 'data',\n * })\n * );\n *\n * // Access the persister for manual control\n * // Clear this specific cache entry\n * dataQuery.persister.clearCache('data');\n *\n * // Clear all cache entries for this store\n * dataQuery.persister.clearAllCache();\n *\n * // Manually trigger garbage collection\n * dataQuery.persister.runGarbageCollection();\n * ```\n */\nexport function insertLocalStoragePersister<\n GroupIdentifier extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n StateType,\n const CacheTime = 300000, // Default cache time in milliseconds (5 minutes)\n>(config: {\n /** Name of your current store, it is mainly used as a prefix for localStorage keys */\n storeName: string;\n /** Key used to identify the specific data within the store */\n key: string;\n /** Whether to wait for the params source to be equal to its previous value before persisting.\n * Mainly useful when params can be undefined at the beginning. (And for single resource).\n * Default is true.\n */\n waitForParamsSrcToBeEqualToPreviousValue?: boolean;\n /**\n * Default cache time in milliseconds.\n * This is the time after which the cached data will be considered stale and eligible for garbage collection.\n * If not specified, the default is 5 minutes (300000 ms).\n */\n cacheTime?: CacheTime;\n}) {\n return (\n context:\n | InsertionResourceFactoryContext<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >\n | InsertionStateFactoryContext<StateType, PreviousInsertionsOutputs>,\n ) => {\n type ResourceByIdContext = InsertionByIdParams<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >;\n type ResourceContext = InsertionParams<\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >;\n const persister = localStoragePersister(config.storeName);\n const hasResourceById = 'resourceById' in context;\n const isUsingIdentifier =\n hasResourceById ||\n ('identifier' in context &&\n typeof (context as unknown as ResourceByIdContext).identifier ===\n 'function');\n const resourceTarget =\n 'resourceById' in context\n ? context.resourceById\n : 'state' in context\n ? (context as any).state\n : (context as ResourceContext).resource;\n\n if (isUsingIdentifier) {\n persister.addQueryByIdToPersist({\n key: config.key,\n cacheTime: (config?.cacheTime as number | undefined) ?? 300000,\n queryByIdResource: resourceTarget as unknown as ResourceByIdRef<\n string,\n unknown,\n unknown\n >,\n queryResourceParamsSrc: (\n context as ResourceByIdContext | ResourceContext\n ).resourceParamsSrc,\n });\n } else {\n persister.addQueryToPersist({\n key: config.key,\n cacheTime: (config?.cacheTime as number | undefined) ?? 300000,\n queryResource: resourceTarget as unknown as ResourceRef<unknown>,\n queryResourceParamsSrc: (\n context as unknown as ResourceByIdContext | ResourceContext\n ).resourceParamsSrc,\n waitForParamsSrcToBeEqualToPreviousValue: true,\n });\n }\n\n return {\n persister,\n };\n };\n}\n","import { linkedSignal, Signal, ValueEqualityFn, signal } from '@angular/core';\nimport { ReadonlySource } from './util/source.type';\nimport { SignalSource } from './signal-source';\nimport { SourceBranded } from './util/util';\n\nexport function linkedSource<SourceState, ComputedValue>(\n signalOrigin: SignalSource<SourceState> | ReadonlySource<SourceState>,\n computedFn: (sourceValue: NoInfer<SourceState>) => ComputedValue,\n options?: {\n equal?: ValueEqualityFn<NoInfer<ComputedValue> | undefined>;\n debugName?: string;\n },\n): SignalSource<ComputedValue> {\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<SourceState, ComputedValue | undefined>({\n source: signalOrigin as Signal<SourceState>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n return computedFn(currentSourceState);\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n },\n SourceBranded,\n ) as SignalSource<ComputedValue>;\n}\n","import {\n computed,\n isSignal,\n resource,\n ResourceLoaderParams,\n ResourceOptions,\n ResourceRef,\n ResourceStatus,\n ResourceStreamingLoader,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { InsertionsResourcesFactory } from './query.core';\nimport { resourceById, ResourceByIdRef } from './resource-by-id';\nimport { ReadonlySource } from './util/source.type';\nimport { MergeObjects } from './util/util.type';\nimport { CraftResourceRef } from './util/craft-resource-ref';\nimport { craftResource } from './craft-resource';\n// todo refactor to share code with AsyncProcess\n\ntype MutationConfig<\n ResourceState,\n Params,\n ParamsArgs,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n> = Omit<ResourceOptions<NoInfer<ResourceState>, Params>, 'params' | 'loader'> &\n (\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * ! It required One parameter at least to be able to generate the method (otherwise it will think it is bind to a source, see below).\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n *\n * It also accepts a ReadonlySource<SourceParams> to connect the mutation params to an external signal source.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n fromResourceById?: never;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n }\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * ! It required One parameter at least to be able to generate the method (otherwise it will think it is bind to a source, see below).\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n *\n * It also accepts a ReadonlySource<SourceParams> to connect the mutation params to an external signal source.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader?: never;\n fromResourceById?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (entity: ResourceRef<NoInfer<FromObjectState>>) => Params;\n loader?: never;\n method?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (\n entity: CraftResourceRef<\n NoInfer<FromObjectState>,\n NoInfer<FromObjectResourceParams>\n >,\n ) => Params;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n }\n | {\n fromResourceById?: never;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (entity: ResourceRef<NoInfer<FromObjectState>>) => Params;\n loader?: never;\n method?: never;\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<\n ResourceState,\n ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >\n >;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById?: never;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: () => Params;\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n loader: (\n param: ResourceLoaderParams<\n NonNullable<\n [unknown] extends [Params]\n ? NoInfer<SourceParams>\n : NoInfer<Params>\n >\n >,\n ) => Promise<ResourceState>;\n stream?: never;\n }\n );\n\nexport type ResourceLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n> = {\n type: 'resourceLike';\n kind: 'mutation';\n} & MergeObjects<\n [\n {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n },\n {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n },\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n Insertions,\n {\n [key in `~InternalType`]: 'Used to avoid TS type erasure';\n },\n ]\n>;\n\nexport type ResourceByIdLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier,\n> = { type: 'resourceByGroupLike'; kind: 'mutation' } & {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n} & {\n _resourceById: ResourceByIdRef<GroupIdentifier & string, Value, Params>;\n /**\n * Get the associated resource by id\n *\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n *\n * return the associated resource or undefined if not existing\n */\n select: (id: GroupIdentifier) =>\n | {\n readonly value: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly safeValue: Signal<Value | undefined>;\n hasValue(): boolean;\n }\n | undefined;\n} & MergeObjects<\n [\n Insertions,\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n ResourceByIdRef<GroupIdentifier & string, Value, Params>,\n ]\n >;\n\nexport type MutationRef<\n Value,\n Params,\n ArgParams,\n Insertions,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n> = [unknown] extends [GroupIdentifier]\n ? ResourceLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions\n >\n : ResourceByIdLikeMutationRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier\n >;\n// & {\n// // ! Otherwise TS erases the types\n// [key in `~InternalType`]: 'Used to avoid TS type erasure';\n// };\n\nexport type MutationOutput<\n State extends object | undefined,\n Params,\n ArgParams,\n SourceParams,\n GroupIdentifier,\n Insertions,\n> = MutationRef<\n State,\n Params,\n ArgParams,\n Insertions,\n [unknown] extends [ArgParams] ? false : true, // ! force to method to have one arg minimum, we can not compare SourceParams type, because it also infer Params\n SourceParams,\n GroupIdentifier\n>;\n\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >,\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\n/**\n * Creates a reactive mutation manager that handles asynchronous operations with state tracking.\n *\n * This function manages mutation state by:\n * - Executing asynchronous operations (loader or stream) when triggered\n * - Tracking operation status (idle, loading, resolved, rejected)\n * - Providing reactive signals for value, status, error, and loading state\n * - Supporting both method-based triggers and source-based automatic execution\n * - Optionally enabling parallel mutation execution by grouping instances with an identifier\n *\n * @remarks\n * **Important:** This function must be called within an injection context.\n *\n * **Mutation Modes:**\n * - **Method-based:** Define a `method` function that returns params. Call `mutate()` to trigger the operation.\n * - **Source-based:** Use `afterRecomputation()` to bind to a source signal. The mutation executes automatically when the source changes.\n * - **Resource-based:** Bind to another `ResourceByIdRef` using `fromResourceById` to sync operations.\n *\n * **With Identifier:**\n * When an `identifier` function is provided, mutations are grouped by ID. Use `select(id)` to access individual mutation instances.\n *\n * @param config - Configuration object containing:\n * - `method`: Function that takes args and returns params, or a `ReadonlySource` for automatic execution\n * - `loader`: Async function that performs the mutation and returns a Promise of the result\n * - `stream` (optional): Async function that returns a signal for streaming results\n * - `identifier` (optional): Function to derive a unique ID from params for grouping mutations\n * - `fromResourceById` (optional): Bind to another ResourceByIdRef for synced operations\n * - `params` (optional): Function to derive params from a resource entity\n * - Additional ResourceOptions like `equal`, `injector`, etc.\n * @param insertions - Optional insertion functions to add custom methods, computed values or side effects to the mutation.\n * Insertions receive context with resource signals (`value`, `status`, `error`, `isLoading`, `hasValue`), `config`, and previous insertions.\n * Methods bound to a source using `afterRecomputation` (effectRef-like) are not exposed in the output.\n * @returns A mutation reference object with:\n * - `value`: Signal containing the mutation result (undefined if not yet executed)\n * - `status`: Signal with current status ('idle' | 'loading' | 'resolved' | 'rejected')\n * - `error`: Signal containing any error that occurred\n * - `isLoading`: Signal indicating if the mutation is currently executing\n * - `hasValue()`: Method to check if a value is available\n * - `mutate(args)`: Method to trigger the mutation (only for method-based mutations)\n * - `source`: The connected source (only for source-based mutations)\n * - `select(id)`: Method to access a specific mutation instance by ID (only when identifier is provided)\n * - Custom methods from insertions (excluding methods bound to sources)\n *\n * @example\n * Basic method-based mutation\n * ```ts\n * const updateUser = mutation({\n * method: (userId: string) => ({ userId }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`, { method: 'PATCH' });\n * return response.json();\n * },\n * });\n *\n * // Check status\n * console.log(updateUser.status()); // 'idle'\n * console.log(updateUser.isLoading()); // false\n *\n * // Trigger mutation\n * updateUser.mutate('user-123');\n * console.log(updateUser.status()); // 'loading'\n *\n * // After completion\n * console.log(updateUser.value()); // { id: 'user-123', name: '...' }\n * console.log(updateUser.status()); // 'resolved'\n * ```\n *\n * @example\n * Source-based automatic mutation\n * ```ts\n * todo change example for mutation\n * const updateUserSource = source<{ userId: string, email: string }>();\n *\n * const updateUser = mutation({\n * method: afterRecomputation(updateUserSource, (params) => params),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`, { method: 'PATCH' });\n * return response.json();\n * },\n * });\n *\n * // Mutation executes automatically when source changes\n * updateUserSource.set({ userId: 'user-123', email: 'newemail@example.com' });\n * console.log(updateUser.status()); // 'loading'\n * ```\n *\n * @example\n * Mutation with identifier for grouping\n * ```ts\n * const deleteItem = mutation({\n * method: (itemId: string) => ({ itemId }),\n * identifier: (params) => params.itemId,\n * loader: async ({ params }) => {\n * await fetch(`/api/items/${params.itemId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * });\n *\n * // Trigger mutations for different items\n * deleteItem.mutate('item-1');\n * deleteItem.mutate('item-2');\n *\n * // Access individual mutation states\n * const item1Mutation = deleteItem.select('item-1');\n * console.log(item1Mutation?.status()); // 'loading' or 'resolved'\n * console.log(item1Mutation?.value()); // { deleted: true }\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const createPost = mutation(\n * {\n * method: (data: { title: string; content: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * },\n * ({ value, isLoading }) => ({\n * isSuccess: computed(() => value() !== undefined && !isLoading()),\n * reset: () => {\n * // Custom reset logic\n * },\n * })\n * );\n *\n * createPost.mutate({ title: 'Hello', content: 'World' });\n * console.log(createPost.isSuccess()); // Custom computed from insertion\n * ```\n *\n * @example\n * Binding to another ResourceByIdRef\n * ```ts\n * // First, create a source mutation by ID\n * const fetchUsers = mutation({\n * method: (userId: string) => ({ userId }),\n * identifier: (params) => params.userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json();\n * },\n * });\n *\n * // Then create a derived mutation that processes the results\n * const processedUsers = mutation({\n * fromResourceById: fetchUsers,\n * params: ({ value, status }) => {\n * // Only process when the source is resolved\n * return status() === 'resolved' ? value() : undefined;\n * },\n * identifier: (params) => params.userId,\n * loader: async ({ params }) => {\n * // Process the user data\n * return {\n * ...params,\n * processed: true,\n * timestamp: Date.now(),\n * };\n * },\n * });\n *\n * // Trigger the source mutation\n * fetchUsers.mutate('user-123');\n *\n * // The derived mutation automatically executes when fetchUsers resolves\n * // Access the processed result\n * const processed = processedUsers.select('user-123');\n * console.log(processed?.value()); // { userId: 'user-123', processed: true, ... }\n * ```\n */\nexport function mutation<\n MutationState extends object | undefined,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n mutationConfig: MutationConfig<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n ...insertions: any[]\n): MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n> {\n const mutationResourceParamsFnSignal =\n //@ts-expect-error if no params, it will create a signal\n mutationConfig.params ?? signal<MutationParams | undefined>(undefined);\n\n const isConnectedToAResourceById = 'fromResourceById' in mutationConfig;\n\n const isConnectedToSource =\n 'method' in mutationConfig && isSignal(mutationConfig.method);\n const isUsingIdentifier = 'identifier' in mutationConfig;\n\n const resourceParamsSrc = isConnectedToSource\n ? mutationConfig.method\n : mutationResourceParamsFnSignal;\n\n const resourceTarget = isUsingIdentifier\n ? resourceById<\n MutationState,\n MutationParams,\n GroupIdentifier & string,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >({\n ...mutationConfig,\n params: resourceParamsSrc,\n identifier: mutationConfig.identifier,\n } as any)\n : craftResource<MutationState, MutationParams>({\n ...mutationConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>);\n\n if (!isUsingIdentifier) {\n Object.assign(resourceTarget, {\n safeValue: computed(() => {\n const resourceRef = resourceTarget as ResourceRef<MutationState>;\n return resourceRef.hasValue() ? resourceRef.value() : undefined;\n }),\n });\n }\n\n return Object.assign(\n resourceTarget,\n // byId is used to helps TS to correctly infer the resourceByGroup\n isUsingIdentifier\n ? {\n /**\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n */\n _resourceById: resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n MutationState,\n MutationParams\n >,\n select: (id: GroupIdentifier) => {\n return computed(() => {\n const list = (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n MutationState,\n MutationParams\n >\n )();\n //@ts-expect-error GroupIdentifier & string is not recognized correctly\n return list[id];\n })();\n },\n }\n : {},\n {\n type: isUsingIdentifier ? 'resourceByGroupLike' : 'resourceLike',\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n MutationParams | undefined\n >,\n mutate:\n isConnectedToAResourceById ||\n ('method' in mutationConfig && isSignal(mutationConfig.method))\n ? undefined\n : (arg: MutationArgsParams) => {\n const result =\n 'method' in mutationConfig\n ? mutationConfig.method?.(arg)\n : undefined;\n // make sure mutationResourceParamsFnSignal.set(result as MutationParams); is set before calling addById\n mutationResourceParamsFnSignal.set(result as MutationParams);\n if (isUsingIdentifier) {\n const id = mutationConfig.identifier?.(arg as any);\n (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n MutationState,\n MutationParams\n >\n ).addById(id as GroupIdentifier & string);\n }\n return result;\n },\n },\n (\n insertions as InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<MutationState>,\n NoInfer<MutationParams>,\n {}\n >[]\n )?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n ...(isUsingIdentifier\n ? {\n resourceById: resourceTarget,\n identifier: mutationConfig.identifier,\n }\n : { resource: resourceTarget }),\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n NoInfer<MutationParams>\n >,\n insertions: acc as {},\n state: resourceTarget.state,\n set: resourceTarget.set,\n update: resourceTarget.update,\n } as any),\n };\n },\n {} as Record<string, unknown>,\n ),\n ) as unknown as MutationOutput<\n MutationState,\n MutationParams,\n MutationArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n >;\n}\n","import {\n assertInInjectionContext,\n computed,\n inject,\n linkedSignal,\n Signal,\n WritableSignal,\n} from '@angular/core';\nimport {\n InsertionsQueryParamsFactory,\n InsertionQueryParamsFactoryContext,\n} from './query.core';\nimport { MergeObjects } from './util/types/util.type';\nimport { FilterSource, IsEmptyObject } from './util/util.type';\nimport { Prettify } from './util/util.type';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nexport interface QueryParamNavigationOptions {\n queryParamsHandling?: 'merge' | 'preserve' | '';\n onSameUrlNavigation?: 'reload' | 'ignore';\n replaceUrl?: boolean;\n skipLocationChange?: boolean;\n}\n\nexport type QueryParamsToState<QueryParamConfigs> = {\n [K in keyof QueryParamConfigs]: 'parse' extends keyof QueryParamConfigs[K]\n ? QueryParamConfigs[K]['parse'] extends (value: string) => infer U\n ? U\n : 'Error1: QueryParamsToState'\n : 'Error2: QueryParamsToState';\n};\n\nexport type QueryParamOutput<QueryParamsType, Insertions, QueryParamsState> =\n Signal<QueryParamsState> &\n MergeObjects<\n [\n {\n [K in keyof QueryParamsState]: Signal<QueryParamsState[K]>;\n },\n IsEmptyObject<Insertions> extends true ? {} : FilterSource<Insertions>,\n {\n _config: QueryParamsType;\n },\n ]\n >;\n\nexport interface QueryParamConfig<T = unknown> {\n fallbackValue: NoInfer<T>;\n parse: (value: string) => T;\n serialize: (value: NoInfer<T>) => string;\n}\n\n/**\n * Creates a reactive query parameter manager that synchronizes state with URL query parameters.\n *\n * This function manages query parameter state by:\n * - Reading initial values from the URL or using default values\n * - Parsing URL strings into typed values using the provided `parse` function\n * - Serializing typed values back to strings for URL updates using the `serialize` function\n * - Providing reactive signals for each query parameter\n *\n * @remarks\n * **Important:** This function must be called within an injection context.\n * If called outside an injection context, it will only return an object containing the configuration under `_config`.\n *\n * @param config - Configuration object containing:\n * - `state`: Record of query parameter configurations, each with `fallbackValue`, `parse`, and `serialize`\n * - `queryParamsHandling` (optional): How to handle existing query params ('merge' | 'preserve' | '')\n * - `onSameUrlNavigation` (optional): Behavior on same URL navigation ('reload' | 'ignore')\n * - `replaceUrl` (optional): Whether to replace the URL in browser history\n * - `skipLocationChange` (optional): Whether to skip updating the browser's location\n * @param insertions - Optional insertion functions to add custom methods, computed values or side effects to the query param manager.\n * Insertions receive context with `state`, `config`, `set`, `update`, `patch`, `reset` and previous insertions.\n * Methods bound to a source using `afterRecomputation` (effectRef-like) are not exposed in the output.\n * @returns A signal that returns the current query parameter state, extended with:\n * - Individual signals for each query parameter (e.g., `queryParam.page()`)\n * - Custom methods from insertions (excluding methods bound to sources)\n * - `_config`: The original configuration\n *\n * @example\n * Basic usage\n * ```ts\n * const myQueryParams = queryParam(\n * {\n * state: {\n * page: {\n * fallbackValue: 1,\n * parse: (value) => parseInt(value, 10),\n * serialize: (value) => String(value),\n * },\n * pageSize: {\n * fallbackValue: 10,\n * parse: (value) => parseInt(value, 10),\n * serialize: (value) => String(value),\n * },\n * },\n * },\n * ({ set, update, patch, reset }) => ({ set, update, patch, reset })\n * );\n *\n * // Access state\n * console.log(myQueryParams()); // { page: 1, pageSize: 10 }\n * console.log(myQueryParams.page()); // 1\n *\n * // Update state (also updates URL)\n * myQueryParams.set({ page: 2, pageSize: 20 });\n * myQueryParams.update(current => ({ ...current, page: current.page + 1 }));\n * myQueryParams.patch({ pageSize: 50 });\n * myQueryParams.reset();\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const myQueryParams = queryParam(\n * {\n * state: {\n * page: { fallbackValue: 1, parse: parseInt, serialize: String },\n * },\n * },\n * ({ state, set }) => ({\n * goTo: (newPage: number) => {\n * set({ ...state(), page: newPage });\n * },\n * })\n * );\n *\n * myQueryParams.goTo(5); // Custom method from insertion\n * ```\n */\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n): QueryParamOutput<QueryParamsType, {}, QueryParamsState>;\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n Insertion1,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n insertion1: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion1\n >,\n): QueryParamOutput<QueryParamsType, Insertion1, QueryParamsState>;\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n Insertion1,\n Insertion2,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n insertion1: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion1\n >,\n insertion2: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion2,\n Insertion1\n >,\n): QueryParamOutput<QueryParamsType, Insertion1 & Insertion2, QueryParamsState>;\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n Insertion1,\n Insertion2,\n Insertion3,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n insertion1: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion1\n >,\n insertion2: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsQueryParamsFactory<\n NoInfer<QueryParamsType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): QueryParamOutput<\n QueryParamsType,\n Insertion1 & Insertion2 & Insertion3,\n QueryParamsState\n>;\n/**\n *\n * If it is not called in an injection context, it returns the config under _config.\n */\nexport function queryParam<\n QueryParamsType extends Record<string, QueryParamConfig<unknown>>,\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n>(\n config: { state: QueryParamsType } & QueryParamNavigationOptions,\n ...insertions: any[]\n): QueryParamOutput<QueryParamsType, {}, QueryParamsState> {\n try {\n assertInInjectionContext(queryParam);\n } catch (e) {\n return {\n _config: config,\n } as any;\n }\n\n const router = inject(Router);\n const activatedRoute = inject(ActivatedRoute);\n\n const { state: queryParamsConfig, ...options } = config;\n\n // Create signals for each query parameter\n const queryParamFromUrl = linkedSignal(() => {\n return (\n router.currentNavigation()?.extractedUrl.queryParams ??\n activatedRoute.snapshot.queryParams\n );\n });\n\n // Create computed signals for each query parameter with parsing\n const queryParamsState = linkedSignal(() =>\n Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n const rawValue = queryParamFromUrl()?.[key];\n if (rawValue === undefined || rawValue === null) {\n acc[key] = config.fallbackValue;\n return acc;\n }\n try {\n acc[key] = config.parse(rawValue);\n return acc;\n } catch {\n acc[key] = config.fallbackValue;\n return acc;\n }\n },\n {} as Record<string, unknown>,\n ),\n ) as WritableSignal<QueryParamsToState<QueryParamsType>>;\n\n // Get initial values from the url or use the fallback values\n const getDefaultState = () =>\n Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n acc[key] = config.fallbackValue;\n return acc;\n },\n {} as Record<string, unknown>,\n ) as QueryParamsToState<QueryParamsType>;\n\n // Save the original set method before we override it\n const originalSet = queryParamsState.set.bind(queryParamsState);\n\n // Navigation helper\n const navigate = (\n newState: QueryParamsToState<QueryParamsType>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n // Update the local state first using the original set method\n originalSet(newState);\n\n // Then navigate without triggering another update\n const mergedOptions = { ...options, ...navOptions };\n // Only include params that differ from their fallback values (SEO optimization)\n const serializedParams = Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n const currentValue = newState[key];\n // Skip if value equals fallback value\n if (currentValue !== config.fallbackValue) {\n acc[key] = config.serialize(currentValue);\n }\n return acc;\n },\n {} as Record<string, string>,\n );\n\n // Use queueMicrotask to avoid call stack issues\n queueMicrotask(() => {\n router.navigate([], {\n relativeTo: activatedRoute,\n queryParams: serializedParams,\n queryParamsHandling: mergedOptions.queryParamsHandling,\n onSameUrlNavigation: mergedOptions.onSameUrlNavigation,\n replaceUrl: mergedOptions.replaceUrl,\n skipLocationChange: mergedOptions.skipLocationChange,\n });\n });\n };\n\n // Create individual property signals\n const props = Object.entries(queryParamsConfig).reduce(\n (acc, [key, config]) => {\n acc[key] = computed(() => queryParamsState()[key]);\n return acc;\n },\n {} as Record<string, Signal<unknown>>,\n );\n\n // Create methods\n const methods = {\n set: (\n params: QueryParamsToState<QueryParamsType>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n navigate(params, navOptions);\n },\n update: (\n updateFn: (\n currentParams: QueryParamsToState<QueryParamsType>,\n ) => QueryParamsToState<QueryParamsType>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n const newState = updateFn(queryParamsState());\n navigate(newState, navOptions);\n },\n patch: (\n params: Partial<QueryParamsToState<QueryParamsType>>,\n navOptions?: QueryParamNavigationOptions,\n ) => {\n const newState = { ...queryParamsState(), ...params };\n navigate(newState, navOptions);\n },\n reset: (navOptions?: QueryParamNavigationOptions) => {\n navigate(getDefaultState(), navOptions);\n },\n };\n\n // Process insertions\n const insertionResults =\n (insertions as InsertionsQueryParamsFactory<QueryParamsType, {}>[])?.reduce(\n (acc, insert) => {\n const newInsertions = insert({\n state: queryParamsState.asReadonly(),\n config: queryParamsConfig,\n ...methods,\n insertions: acc as {},\n } as InsertionQueryParamsFactoryContext<QueryParamsType, {}>);\n return {\n ...acc,\n ...newInsertions,\n };\n },\n {} as Record<string, unknown>,\n ) || {};\n\n return Object.assign(queryParamsState.asReadonly(), props, insertionResults, {\n _config: config,\n }) as unknown as QueryParamOutput<QueryParamsType, {}, QueryParamsState>;\n}\n","import {\n computed,\n isSignal,\n ResourceLoaderParams,\n ResourceOptions,\n ResourceRef,\n ResourceStatus,\n ResourceStreamingLoader,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { InsertionsResourcesFactory } from './query.core';\nimport { resourceById, ResourceByIdRef } from './resource-by-id';\nimport { ReadonlySource } from './util/source.type';\nimport { MergeObjects } from './util/util.type';\nimport { preservedResource } from './preserved-resource';\nimport { craftResource } from './craft-resource';\n\ntype QueryConfig<\n ResourceState,\n Params,\n ParamsArgs,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n> = Omit<ResourceOptions<NoInfer<ResourceState>, Params>, 'params' | 'loader'> &\n (\n | {\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: () => Params;\n loader: (\n param: NoInfer<ResourceLoaderParams<Params>>,\n ) => Promise<ResourceState>;\n method?: never;\n fromResourceById?: never;\n stream?: never;\n /**\n * Each the query load, the value will return undefined.\n * To avoid flickering display and also enable to the data to be retrieved from cache, use () => true\n * default value: true\n */\n preservePreviousValue?: () => boolean;\n }\n | {\n /**\n * Used to generate a method in the store, when called will trigger the resource loader/stream.\n *\n * Only support one parameter which can be an object to pass multiple parameters.\n *\n * It also accepts a ReadonlySource<SourceParams> to connect the query params to an external signal source.\n */\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader: (\n param: NoInfer<ResourceLoaderParams<Params>>,\n ) => Promise<ResourceState>;\n params?: never;\n fromResourceById?: never;\n stream?: never;\n preservePreviousValue?: () => boolean;\n }\n | {\n method?: never;\n loader?: never;\n params?: () => Params;\n fromResourceById?: never;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<ResourceState, Params>;\n preservePreviousValue?: () => boolean;\n }\n | {\n method: ((args: ParamsArgs) => Params) | ReadonlySource<SourceParams>;\n loader?: never;\n params?: never;\n fromResourceById?: never;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<ResourceState, Params>;\n preservePreviousValue?: () => boolean;\n }\n | {\n /**\n * Use it, when you need to bind a ResourceByIdRef to another ResourceByIdRef.\n * It will enforce the fromObject keys syncing when the fromObject resource change.\n */\n fromResourceById: ResourceByIdRef<\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >;\n /**\n * A reactive function which determines the request to be made. Whenever the request changes, the\n * loader will be triggered to fetch a new value for the resource.\n *\n * If a request function isn't provided, the loader won't rerun unless the resource is reloaded.\n */\n params: (entity: ResourceRef<NoInfer<FromObjectState>>) => Params;\n loader: (\n param: NoInfer<ResourceLoaderParams<Params>>,\n ) => Promise<ResourceState>;\n method?: never;\n stream?: never;\n /**\n * Each the query load, the value will return undefined.\n * To avoid flickering display and also enable to the data to be retrieved from cache, use () => true\n * default value: true\n */\n preservePreviousValue?: () => boolean;\n }\n | {\n method?: never;\n loader?: never;\n params?: () => Params;\n fromResourceById?: never;\n /**\n * Loading function which returns a `Promise` of a signal of the resource's value for a given\n * request, which can change over time as new values are received from a stream.\n */\n stream: ResourceStreamingLoader<ResourceState, Params>;\n preservePreviousValue?: () => boolean;\n }\n ) & {\n /**\n * A unique identifier for the resource, derived from the params.\n * It should be a string that uniquely identifies the resource based on the params.\n */\n identifier?: (params: NoInfer<NonNullable<Params>>) => GroupIdentifier;\n /**\n * Under the hood, a resource is generated for each new identifier generated when the params source change.\n *\n * If the source change, and their is an existing resource with the same identifier, it will be re-used.\n *\n * In this case, when the source is an object, an existing resource can be retrieved by the matching his record key with identifier function, but as the reference change it will trigger the loading of the resource again.\n *\n * To avoid this, you can use this option to tell how to compare the incoming params with the existing params of the resource.\n * - 'useIdentifier': will use the identifier function to compare the previous params and the incoming params. This very useful when using pagination.\n * - 'default' (default value): will use a strict equality check (===) between the previous params and the incoming params.\n * - (a: Params, b: Params) => boolean: you can provide your own comparison function to compare the previous params and the incoming params. This is useful when you want to compare specific fields of the params.\n *\n * Note: if your params is a primitive (string, number, boolean, etc.), you don't need to use this option since the strict equality check will work as expected.\n *\n * For **query** that use 'identifier', the default value is 'useIdentifier'\n *\n * For **query** that don't use 'identifier', the default value is 'default'\n */\n equalParams?: Params extends object\n ?\n | 'default'\n | 'useIdentifier'\n | ((\n a: Params,\n b: Params,\n identifierFn: (params: Params) => GroupIdentifier,\n ) => boolean)\n : never;\n };\n\nexport type ResourceLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n> = {\n type: 'resourceLike';\n kind: 'query';\n} & MergeObjects<\n [\n {\n readonly value: Signal<Value | undefined>;\n /**\n * Avoids to throw error when accessing value during error state\n */\n readonly safeValue: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n hasValue(): boolean;\n },\n {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n },\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n Insertions,\n {\n [key in `~InternalType`]: 'Used to avoid TS type erasure';\n },\n ]\n>;\n\nexport type ResourceByIdLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier,\n> = { type: 'resourceByGroupLike'; kind: 'query' } & {\n readonly resourceParamsSrc: WritableSignal<NoInfer<Params>>;\n} & {\n _resourceById: ResourceByIdRef<GroupIdentifier & string, Value, Params>;\n /**\n * Get the associated resource by id\n *\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n *\n * return the associated resource or undefined if not existing\n */\n select: (id: GroupIdentifier) =>\n | {\n readonly value: Signal<Value | undefined>;\n /**\n * Avoids to throw error when accessing value during error state\n */\n readonly safeValue: Signal<Value | undefined>;\n readonly status: Signal<ResourceStatus>;\n readonly error: Signal<Error | undefined>;\n readonly isLoading: Signal<boolean>;\n hasValue(): boolean;\n }\n | undefined;\n} & MergeObjects<\n [\n Insertions,\n IsMethod extends true\n ? {\n mutate: (args: ArgParams) => Params;\n }\n : {\n source: ReadonlySource<SourceParams>;\n },\n ResourceByIdRef<GroupIdentifier & string, Value, Params>,\n ]\n >;\n\nexport type QueryRef<\n Value,\n Params,\n ArgParams,\n Insertions,\n IsMethod,\n SourceParams,\n GroupIdentifier,\n> = [unknown] extends [GroupIdentifier]\n ? ResourceLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions\n >\n : ResourceByIdLikeQueryRef<\n Value,\n Params,\n IsMethod,\n ArgParams,\n SourceParams,\n Insertions,\n GroupIdentifier\n >;\n\nexport type QueryOutput<\n State extends object | undefined,\n Params,\n ArgParams,\n SourceParams,\n GroupIdentifier,\n Insertions,\n> = QueryRef<\n State,\n Params,\n ArgParams,\n Insertions,\n [unknown] extends [ArgParams] ? false : true, // ! force to method to have one arg minimum, we can not compare SourceParams type, because it also infer Params\n SourceParams,\n GroupIdentifier\n>;\n\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n insertion1: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion1\n >,\n insertion2: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >,\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\n/**\n * Creates a reactive query manager that handles data fetching with automatic state tracking.\n *\n * This function manages query state by:\n * - Executing asynchronous fetch operations (loader or stream) automatically when params change\n * - Tracking operation status (idle, loading, resolved, rejected)\n * - Providing reactive signals for value, status, error, and loading state\n * - Supporting both params-based automatic execution and method-based manual triggers\n * - Optionally enabling parallel query execution by grouping instances with an identifier\n * - Caching and reusing query results based on params\n *\n * @remarks\n * **Important:** This function must be called within an injection context.\n *\n * **Query Modes:**\n * - **Params-based (automatic):** Define a `params` function. The query executes automatically when params change.\n * - **Method-based (manual):** Define a `method` function that returns params. Call `mutate()` to trigger execution.\n * - **Source-based (reactive):** Bind to a `ReadonlySource` for automatic execution when the source changes.\n * - **Resource-based (derived):** Bind to another `ResourceByIdRef` using `fromResourceById` to create derived queries.\n *\n * **With Identifier:**\n * When an `identifier` function is provided, queries are grouped by ID enabling parallel execution and individual result tracking.\n * Use `select(id)` to access individual query instances.\n *\n * **Caching & Performance:**\n * - Use `preservePreviousValue: () => true` to prevent flickering by keeping previous data while loading\n * - Use `equalParams` to control when queries should re-execute based on params comparison\n *\n * @param config - Configuration object containing:\n * - `params`: Function that returns params for automatic execution, or undefined for method-based queries\n * - `method`: Function that takes args and returns params for manual execution, or a `ReadonlySource` for reactive execution\n * - `loader`: Async function that performs the query and returns a Promise of the result\n * - `stream` (optional): Async function that returns a signal for streaming results\n * - `identifier` (optional): Function to derive a unique ID from params for grouping queries\n * - `fromResourceById` (optional): Bind to another ResourceByIdRef for derived queries\n * - `preservePreviousValue` (optional): Function returning boolean to keep previous value while reloading\n * - `equalParams` (optional): Controls params comparison ('default' | 'useIdentifier' | custom function)\n * - Additional ResourceOptions like `equal`, `injector`, etc.\n * @param insertions - Optional insertion functions to add custom methods, computed values or side effects to the query.\n * Insertions receive context with resource signals (`value`, `status`, `error`, `isLoading`, `hasValue`), `config`, and previous insertions.\n * @returns A query reference object with:\n * - `value`: Signal containing the query result (undefined if not yet executed)\n * - `status`: Signal with current status ('idle' | 'loading' | 'resolved' | 'rejected')\n * - `error`: Signal containing any error that occurred\n * - `isLoading`: Signal indicating if the query is currently executing\n * - `hasValue()`: Method to check if a value is available\n * - `mutate(args)`: Method to trigger the query manually (only for method-based queries)\n * - `source`: The connected source (only for source-based queries)\n * - `select(id)`: Method to access a specific query instance by ID (only when identifier is provided)\n * - `resourceParamsSrc`: The underlying params signal\n * - Custom methods from insertions\n *\n * @example\n * Basic params-based automatic query\n * ```ts\n * const userIdSignal = signal('user-123');\n *\n * const userQuery = query({\n * params: () => userIdSignal(),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Query executes automatically when created and when userIdSignal changes\n * console.log(userQuery.status()); // 'loading'\n * // After completion\n * console.log(userQuery.value()); // { id: 'user-123', name: '...' }\n * console.log(userQuery.status()); // 'resolved'\n *\n * // Changing the signal triggers a new query\n * userIdSignal.set('user-456');\n * ```\n *\n * @example\n * Method-based manual query\n * ```ts\n * const searchQuery = query({\n * method: (searchTerm: string) => ({ term: searchTerm }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/search?q=${params.term}`);\n * return response.json();\n * },\n * });\n *\n * // Query doesn't execute automatically\n * console.log(searchQuery.status()); // 'idle'\n *\n * // Manually trigger the query\n * searchQuery.mutate('angular');\n * console.log(searchQuery.status()); // 'loading'\n * ```\n *\n * @example\n * Query with identifier for parallel execution\n * ```ts\n * const userDetailsQuery = query({\n * params: () => currentUserId(),\n * identifier: (userId) => userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Multiple users can be queried in parallel\n * // Each has its own state tracked by identifier\n * const user1 = userDetailsQuery.select('user-1');\n * const user2 = userDetailsQuery.select('user-2');\n *\n * console.log(user1?.status()); // 'resolved'\n * console.log(user1?.value()); // { id: 'user-1', ... }\n * console.log(user2?.status()); // 'loading'\n * ```\n *\n * @example\n * With custom methods via insertions\n * ```ts\n * const todosQuery = query(\n * {\n * params: () => ({ completed: showCompleted() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos?completed=${params.completed}`);\n * return response.json();\n * },\n * },\n * ({ value, isLoading }) => ({\n * count: computed(() => value()?.length ?? 0),\n * isEmpty: computed(() => !isLoading() && value()?.length === 0),\n * })\n * );\n *\n * console.log(todosQuery.count()); // Custom computed from insertion\n * console.log(todosQuery.isEmpty()); // true/false\n * ```\n *\n * @example\n * Streaming query\n * ```ts\n * const liveDataQuery = query({\n * params: () => ({ channel: currentChannel() }),\n * stream: async ({ params }) => {\n * const response = await fetch(`/api/stream/${params.channel}`);\n *\n * // Return a signal that updates as stream data arrives\n * const resultSignal = signal([]);\n * const reader = response.body?.getReader();\n * // ... process stream and update resultSignal\n * return resultSignal;\n * },\n * });\n *\n * // value() updates continuously as stream data arrives\n * ```\n *\n * @example\n * Derived query from another ResourceByIdRef\n * ```ts\n * // First query fetches basic user data\n * const usersQuery = query({\n * params: () => currentUserId(),\n * identifier: (userId) => userId,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Derived query enriches user data with additional info\n * const enrichedUsersQuery = query({\n * fromResourceById: usersQuery,\n * params: ({ value, status }) => {\n * // Only process when source is resolved\n * return status() === 'resolved' ? value() : undefined;\n * },\n * identifier: (user) => user.id,\n * loader: async ({ params }) => {\n * // Fetch additional data for the user\n * const response = await fetch(`/api/users/${params.id}/details`);\n * const details = await response.json();\n * return { ...params, ...details };\n * },\n * });\n *\n * // Derived query executes automatically when usersQuery resolves\n * const enrichedUser = enrichedUsersQuery.select('user-123');\n * console.log(enrichedUser?.value()); // { ...userData, ...details }\n * ```\n */\nexport function query<\n QueryState extends object | undefined,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier extends string,\n FromObjectState,\n FromObjectResourceParams,\n>(\n queryConfig: QueryConfig<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n FromObjectGroupIdentifier,\n FromObjectState,\n FromObjectResourceParams\n >,\n ...insertions: any[]\n): QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n> {\n const hasParamsFn = typeof queryConfig.method === 'function';\n const queryResourceParamsFnSignal =\n queryConfig.params ?? signal<QueryParams | undefined>(undefined);\n\n const isConnectedToSource = isSignal(queryConfig.method);\n const isUsingIdentifier = 'identifier' in queryConfig;\n\n const resourceParamsSrc = isConnectedToSource\n ? queryConfig.method\n : queryResourceParamsFnSignal;\n\n const resourceTarget = isUsingIdentifier\n ? resourceById<\n QueryState,\n QueryParams,\n GroupIdentifier & string,\n string,\n unknown,\n unknown\n >({\n ...queryConfig,\n params: resourceParamsSrc,\n identifier: queryConfig.identifier,\n equalParams: queryConfig.equalParams ?? 'useIdentifier',\n } as any)\n : !queryConfig.preservePreviousValue || queryConfig.preservePreviousValue()\n ? preservedResource<QueryState, QueryParams>({\n ...queryConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>)\n : craftResource<QueryState, QueryParams>({\n ...queryConfig,\n params: resourceParamsSrc,\n } as ResourceOptions<any, any>);\n\n const queryOutputWithoutInsertions = Object.assign(\n resourceTarget,\n // byId is used to helps TS to correctly infer the resourceByGroup\n isUsingIdentifier\n ? {\n /**\n * Only added to help TS inference (TS cannot infer ResourceByIdHandler without erasing the signal getter, () => ResourceByIdRef<...>) )\n */\n _resourceById: resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n QueryState,\n QueryParams\n >,\n select: (id: GroupIdentifier) => {\n return computed(() => {\n const list = (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n QueryState,\n QueryParams\n >\n )();\n //@ts-expect-error GroupIdentifier & string is not recognized correctly\n return list[id];\n })();\n },\n }\n : {},\n {\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n QueryParams | undefined\n >,\n method:\n hasParamsFn || isSignal(queryConfig.method)\n ? undefined\n : (arg: QueryArgsParams) => {\n const result = (\n queryConfig.method as unknown as (\n args: QueryArgsParams,\n ) => QueryParams\n )(arg);\n if (isUsingIdentifier) {\n const id = queryConfig.identifier?.(arg as any);\n (\n resourceTarget as ResourceByIdRef<\n GroupIdentifier & string,\n QueryState,\n QueryParams\n >\n ).addById(id as GroupIdentifier & string);\n }\n //@ts-expect-error if method is exposed params can not be of type (entity: ResourceRef<NoInfer<FromObjectState>>) => QueryParams\n queryResourceParamsFnSignal.set(result as QueryParams);\n return result;\n },\n },\n );\n\n return Object.assign(\n queryOutputWithoutInsertions,\n (\n insertions as InsertionsResourcesFactory<\n NoInfer<GroupIdentifier>,\n NoInfer<QueryState>,\n NoInfer<QueryParams>,\n {}\n >[]\n )?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n ...(isUsingIdentifier\n ? {\n resourceById: resourceTarget,\n identifier: queryConfig.identifier,\n }\n : { resource: resourceTarget }),\n resourceParamsSrc: resourceParamsSrc as WritableSignal<\n NoInfer<QueryParams>\n >,\n insertions: acc as {},\n state: resourceTarget.state,\n set: resourceTarget.set,\n update: resourceTarget.update,\n } as any), // try to improve the type here\n };\n },\n {} as Record<string, unknown>,\n ),\n ) as unknown as QueryOutput<\n QueryState,\n QueryParams,\n QueryArgsParams,\n SourceParams,\n GroupIdentifier,\n {}\n >;\n}\n","import { linkedSignal, Signal, signal, ValueEqualityFn } from '@angular/core';\nimport { SourceBranded } from './util/util';\n\nexport type SignalSource<T> = Signal<T | undefined> & {\n set: (value: T) => void;\n preserveLastValue: Signal<T | undefined>;\n} & SourceBranded;\n\n/**\n * Creates a source for event-driven communication with lazy emission semantics.\n *\n * Sources are the foundation of event-driven patterns in ng-craft, enabling:\n * - Discrete event emissions (unlike continuous signals)\n * - Lazy behavior (undefined until explicitly set)\n * - Decoupled communication between components and stores\n * - Automatic triggering of queries, mutations, and async methods\n * - Multi-listener support with independent subscription timing\n *\n * @remarks\n * **Core Concept:**\n * Sources implement event emitter pattern with reactive semantics:\n * - Emit only when explicitly set (not on every read like signals)\n * - Listeners receive `undefined` on first read (lazy semantics)\n * - New listeners don't receive previous emissions by default\n * - Use `preserveLastValue` to get the last emitted value immediately\n *\n * **Difference from Signals:**\n * - **Signals**: Always have a value, recompute on access, continuous state\n * - **Sources**: Emit on explicit set, lazy by default, discrete events\n * - Sources are for events/actions, signals are for state\n *\n * **Use Cases:**\n * - **User actions**: Button clicks, form submissions, custom events\n * - **Navigation events**: Route changes, tab switches\n * - **Data events**: Reload triggers, refresh requests\n * - **Coordination**: Communication between disconnected components\n * - **Store inputs**: Triggering queries/mutations from components\n * - **Event buses**: Decoupled event communication\n *\n * **Integration with Queries/Mutations:**\n * - Bind to method using `afterRecomputation(source, callback)`\n * - Query/mutation executes automatically when source emits\n * - No manual method exposed (source-based triggering)\n *\n * **Listener Semantics:**\n * - **Standard listener**: Returns `undefined` until source emits, then returns new values only\n * - **preserveLastValue**: Returns last emitted value immediately, then tracks new values\n * - Useful for late subscribers that need current state\n *\n * **Limitations:**\n * Sources are signals and behave differently from observables.\n * Understanding these three key limitations is important:\n * - **Multiple sets in same cycle**: When a source is set multiple times during the same cycle\n * (between the first set and the Change Detection that executes all consumer callbacks),\n * consumers will only react once during CD and will only see the last set value.\n * Intermediate values are discarded.\n * - **Multiple sources order**: Within the same cycle, if multiple sources are triggered,\n * consumers cannot determine the order in which the sources were set.\n * The original emission sequence is not preserved.\n * - **Consumer execution order**: When multiple sources are triggered in the same cycle,\n * consumer callbacks are invoked in the order they were declared, not in the order\n * their source producers were triggered.\n * - **No synchronous intermediate value reactions**: Unlike observables, sources cannot react\n * to each intermediate value synchronously. A mechanism similar to observables\n * (or using native Observable API) without RxJS is being considered to enable\n * synchronous reactions to intermediate values, matching the behavior currently\n * offered by observables.\n *\n * @template T - The type of values emitted by the source\n *\n * @param options - Optional configuration:\n * - `equal`: Custom equality function for change detection (prevents duplicate emissions)\n * - `debugName`: Name for debugging purposes\n *\n * @returns A source object with:\n * - `()`: Read current value (undefined until first emission)\n * - `set(value)`: Emit a value to all listeners\n * - `preserveLastValue`: Alternative signal that returns last value immediately\n *\n * @example\n * Basic source for user actions\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * loadUser: source<string>(),\n * }),\n * craftQuery('user', ({ loadUser }) =>\n * query({\n * method: afterRecomputation(loadUser, (userId) => userId),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Query executes automatically when source emits\n * store.setLoadUser('user-123');\n * // -> loadUser source emits 'user-123'\n * // -> user query executes with params 'user-123'\n *\n * store.setLoadUser('user-456');\n * // -> user query executes again with params 'user-456'\n * ```\n *\n * @example\n * Source for form submission\n * ```ts\n * type FormData = { name: string; email: string };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * submitForm: source<FormData>(),\n * }),\n * craftMutations(({ submitForm }) => ({\n * submit: mutation({\n * method: afterRecomputation(submitForm, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // In component template:\n * // <form (submit)=\"onSubmit()\">\n * // <input name=\"name\" [(ngModel)]=\"formData.name\" />\n * // <input name=\"email\" [(ngModel)]=\"formData.email\" />\n * // </form>\n *\n * onSubmit() {\n * // Mutation executes automatically\n * this.store.setSubmitForm(this.formData);\n * // -> submitForm source emits\n * // -> submit mutation executes\n * }\n * ```\n *\n * @example\n * Source for reload/refresh actions\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * reload: source<void>(),\n * }),\n * craftQuery('data', ({ reload }) =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * },\n * insertReloadOnSource(reload)\n * )\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Trigger reload from anywhere\n * store.setReload();\n * // -> reload source emits\n * // -> query reloads\n *\n * // In component:\n * // <button (click)=\"store.setReload()\">Refresh</button>\n * ```\n *\n * @example\n * Multiple sources for different actions\n * ```ts\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * addTodo: source<{ text: string }>(),\n * deleteTodo: source<string>(),\n * toggleTodo: source<string>(),\n * }),\n * craftMutations(({ addTodo, deleteTodo, toggleTodo }) => ({\n * create: mutation({\n * method: afterRecomputation(addTodo, (data) => data),\n * loader: async ({ params }) => {\n * const response = await fetch('/api/todos', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * }),\n * delete: mutation({\n * method: afterRecomputation(deleteTodo, (id) => id),\n * loader: async ({ params }) => {\n * await fetch(`/api/todos/${params}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * }),\n * toggle: mutation({\n * method: afterRecomputation(toggleTodo, (id) => id),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/todos/${params}/toggle`, {\n * method: 'PATCH',\n * });\n * return response.json();\n * },\n * }),\n * }))\n * );\n *\n * const store = injectCraft();\n *\n * // Different actions trigger different mutations\n * store.setAddTodo({ text: 'Buy milk' });\n * store.setToggleTodo('todo-123');\n * store.setDeleteTodo('todo-456');\n * ```\n *\n * @example\n * Late listener with preserveLastValue\n * ```ts\n * const mySource = source<string>();\n *\n * // Early listener\n * const listener1 = computed(() => mySource());\n * console.log(listener1()); // undefined\n *\n * // Emit value\n * mySource.set('Hello');\n * console.log(listener1()); // 'Hello'\n *\n * // Late listener (after emission)\n * const listener2 = computed(() => mySource());\n * console.log(listener2()); // undefined (doesn't get previous emission)\n *\n * mySource.set('World');\n * console.log(listener1()); // 'World'\n * console.log(listener2()); // 'World'\n *\n * // Using preserveLastValue for late listeners\n * const listener3 = computed(() => mySource.preserveLastValue());\n * console.log(listener3()); // 'World' (gets last value immediately)\n * ```\n *\n * @example\n * Custom equality to prevent duplicate emissions\n * ```ts\n * type Params = { id: string; timestamp: number };\n *\n * const paramsSource = source<Params>({\n * equal: (a, b) => a?.id === b?.id, // Compare only by id\n * });\n *\n * const listener = computed(() => paramsSource());\n *\n * paramsSource.set({ id: 'item-1', timestamp: Date.now() });\n * // -> listener receives value\n *\n * paramsSource.set({ id: 'item-1', timestamp: Date.now() });\n * // -> listener does NOT receive value (same id)\n *\n * paramsSource.set({ id: 'item-2', timestamp: Date.now() });\n * // -> listener receives value (different id)\n * ```\n *\n * @example\n * Source for coordinating multiple components\n * ```ts\n * // Global source (outside component)\n * const refreshAllSource = source<void>();\n *\n * // Component A\n * @Component({\n * selector: 'app-data-view',\n * template: '...',\n * })\n * export class DataViewComponent {\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('data', () =>\n * query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/data');\n * return response.json();\n * },\n * },\n * insertReloadOnSource(refreshAllSource)\n * )\n * )\n * );\n *\n * store = this.injectCraft();\n * }\n *\n * // Component B\n * @Component({\n * selector: 'app-refresh-button',\n * template: '<button (click)=\"refresh()\">Refresh All</button>',\n * })\n * export class RefreshButtonComponent {\n * refresh() {\n * // Triggers refresh in all components listening to this source\n * refreshAllSource.set();\n * }\n * }\n * ```\n *\n * @example\n * Source with complex payload\n * ```ts\n * type SearchParams = {\n * query: string;\n * filters: string[];\n * page: number;\n * };\n *\n * const { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftSources({\n * search: source<SearchParams>(),\n * }),\n * craftQuery('results', ({ search }) =>\n * query({\n * method: afterRecomputation(search, (params) => params),\n * loader: async ({ params }) => {\n * const queryString = new URLSearchParams({\n * q: params.query,\n * filters: params.filters.join(','),\n * page: String(params.page),\n * });\n * const response = await fetch(`/api/search?${queryString}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * const store = injectCraft();\n *\n * // Emit complex search parameters\n * store.setSearch({\n * query: 'angular',\n * filters: ['tutorial', 'advanced'],\n * page: 1,\n * });\n * ```\n */\nexport function signalSource<T>(options?: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n debugName?: string;\n}): SignalSource<T> {\n const sourceState = signal<T | undefined>(undefined, {\n ...(options?.equal && { equal: options?.equal }), // add the equal function here, it may helps to detect changes when using scalar values\n ...(options?.debugName && {\n debugName: options?.debugName + '_sourceState',\n }),\n });\n\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<T, T | undefined>({\n source: sourceState as Signal<T>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n\n return currentSourceState;\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n set: sourceState.set,\n },\n SourceBranded,\n ) as SignalSource<T>;\n}\n","import {\n assertInInjectionContext,\n DestroyRef,\n inject,\n ValueEqualityFn,\n} from '@angular/core';\nimport { SignalSource, signalSource } from './signal-source';\n\nexport type SourceFromEvent<T> = SignalSource<T> & {\n dispose: () => void;\n};\n\n/**\n * Creates a source from DOM events with automatic cleanup on component destruction.\n *\n * This function bridges DOM events with ng-craft's reactive system by:\n * - Converting native DOM events to source emissions\n * - Automatically removing event listeners on component destruction\n * - Supporting optional event payload transformation\n * - Providing manual disposal capability\n * - Enabling event-driven query/mutation triggering\n *\n * @remarks\n * **Automatic Cleanup:**\n * - Event listeners are automatically removed when the injection context is destroyed\n * - Uses Angular's `DestroyRef` for lifecycle management\n * - Manual cleanup available via `dispose()` method\n * - Prevents memory leaks from dangling event listeners\n *\n * **Use Cases:**\n * - **User interactions**: Click, input, scroll, keyboard events\n * - **Window events**: Resize, scroll, focus, online/offline\n * - **Document events**: Visibility changes, custom events\n * - **Media events**: Video/audio play, pause, ended\n * - **Form events**: Submit, change, input\n * - **Custom events**: Application-specific DOM events\n *\n * **Event Transformation:**\n * - Without `computedValue`: Emits the raw event object\n * - With `computedValue`: Transforms event before emission\n * - Useful for extracting specific event properties\n * - Reduces payload size and improves type safety\n *\n * **Integration with Stores:**\n * - Use source in queries/mutations via `afterRecomputation()`\n * - Trigger async operations on DOM events\n * - Coordinate multiple components via event sources\n *\n * **Injection Context:**\n * - Must be called within Angular injection context\n * - Typically called in component constructor or class fields\n * - Uses `assertInInjectionContext()` for safety\n *\n * @template T - The type of the event object\n * @template ComputedValue - The type after optional transformation\n *\n * @param target - The DOM element or event target to listen to.\n * Can be any EventTarget (HTMLElement, Window, Document, etc.)\n *\n * @param eventName - The name of the event to listen for.\n * Standard DOM event names: 'click', 'input', 'scroll', etc.\n *\n * @param options - Optional configuration:\n * - `event`: Event listener options (capture, passive, once, etc.)\n * - `computedValue`: Function to transform event before emission\n * - `source`: Source options (equal, debugName)\n *\n * @returns A source that emits on DOM events with:\n * - All standard source capabilities (set, preserveLastValue)\n * - `dispose()`: Method to manually remove event listener\n * - Automatic cleanup on component destruction\n *\n * @example\n * Basic click event source\n * ```ts\n * @Component({\n * selector: 'app-clicker',\n * template: '<button #btn>Click me</button>',\n * })\n * export class ClickerComponent {\n * @ViewChild('btn', { read: ElementRef }) button!: ElementRef<HTMLButtonElement>;\n *\n * clickSource = sourceFromEvent<MouseEvent>(\n * this.button.nativeElement,\n * 'click'\n * );\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftMutations(() => ({\n * trackClick: mutation({\n * method: afterRecomputation(this.clickSource, (event) => ({\n * x: event.clientX,\n * y: event.clientY,\n * })),\n * loader: async ({ params }) => {\n * await fetch('/api/track-click', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return { tracked: true };\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n *\n * // Mutation executes automatically on click\n * }\n * ```\n *\n * @example\n * Window scroll event with transformation\n * ```ts\n * @Component({\n * selector: 'app-infinite-scroll',\n * template: '...',\n * })\n * export class InfiniteScrollComponent {\n * scrollSource = sourceFromEvent(window, 'scroll', {\n * computedValue: () => ({\n * scrollY: window.scrollY,\n * scrollHeight: document.documentElement.scrollHeight,\n * clientHeight: window.innerHeight,\n * }),\n * event: { passive: true }, // Optimize performance\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftAsyncProcesses(() => ({\n * checkLoadMore: asyncProcess({\n * method: afterRecomputation(this.scrollSource, (data) => data),\n * loader: async ({ params }) => {\n * const { scrollY, scrollHeight, clientHeight } = params;\n * const nearBottom = scrollY + clientHeight >= scrollHeight - 100;\n *\n * if (nearBottom) {\n * // Load more data\n * const response = await fetch('/api/load-more');\n * return response.json();\n * }\n * return null;\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n * }\n * ```\n *\n * @example\n * Form input event for real-time validation\n * ```ts\n * @Component({\n * selector: 'app-search',\n * template: '<input #searchInput type=\"text\" placeholder=\"Search...\" />',\n * })\n * export class SearchComponent {\n * @ViewChild('searchInput', { read: ElementRef }) input!: ElementRef<HTMLInputElement>;\n *\n * inputSource = sourceFromEvent(this.input.nativeElement, 'input', {\n * computedValue: (event: Event) => {\n * const target = event.target as HTMLInputElement;\n * return target.value;\n * },\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('results', () =>\n * query({\n * method: afterRecomputation(this.inputSource, (term) => term),\n * loader: async ({ params }) => {\n * if (params.length < 3) return [];\n *\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n *\n * // Query executes on input changes\n * }\n * ```\n *\n * @example\n * Window resize event with debouncing\n * ```ts\n * @Component({\n * selector: 'app-responsive',\n * template: '...',\n * })\n * export class ResponsiveComponent {\n * resizeSource = sourceFromEvent(window, 'resize', {\n * computedValue: () => ({\n * width: window.innerWidth,\n * height: window.innerHeight,\n * }),\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftState('dimensions', () =>\n * state({ width: window.innerWidth, height: window.innerHeight }, {\n * bindSources: {\n * resize: afterRecomputation(this.resizeSource, (data) => data),\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n *\n * // Dimensions state updates on resize\n * }\n * ```\n *\n * @example\n * Custom DOM event\n * ```ts\n * @Component({\n * selector: 'app-custom-events',\n * template: '<div #container></div>',\n * })\n * export class CustomEventsComponent {\n * @ViewChild('container', { read: ElementRef }) container!: ElementRef<HTMLDivElement>;\n *\n * customEventSource = sourceFromEvent<CustomEvent<{ data: string }>>(\n * this.container.nativeElement,\n * 'custom-event',\n * {\n * computedValue: (event) => event.detail.data,\n * }\n * );\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftAsyncProcesses(() => ({\n * handleCustomEvent: asyncProcess({\n * method: afterRecomputation(this.customEventSource, (data) => data),\n * loader: async ({ params }) => {\n * console.log('Custom event data:', params);\n * return { processed: true };\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n *\n * triggerCustomEvent() {\n * const event = new CustomEvent('custom-event', {\n * detail: { data: 'Hello from custom event' },\n * });\n * this.container.nativeElement.dispatchEvent(event);\n * }\n * }\n * ```\n *\n * @example\n * Manual disposal for dynamic elements\n * ```ts\n * @Component({\n * selector: 'app-dynamic',\n * template: '...',\n * })\n * export class DynamicComponent {\n * private clickSource?: SourceFromEvent<MouseEvent>;\n *\n * attachListener(element: HTMLElement) {\n * // Remove previous listener if exists\n * this.clickSource?.dispose();\n *\n * // Attach to new element\n * this.clickSource = sourceFromEvent<MouseEvent>(element, 'click');\n *\n * // Use in store\n * // ...\n * }\n *\n * detachListener() {\n * // Manually remove listener before component destruction\n * this.clickSource?.dispose();\n * this.clickSource = undefined;\n * }\n * }\n * ```\n *\n * @example\n * Multiple event sources for keyboard shortcuts\n * ```ts\n * @Component({\n * selector: 'app-shortcuts',\n * template: '...',\n * })\n * export class ShortcutsComponent {\n * keydownSource = sourceFromEvent(document, 'keydown', {\n * computedValue: (event: KeyboardEvent) => ({\n * key: event.key,\n * ctrlKey: event.ctrlKey,\n * shiftKey: event.shiftKey,\n * altKey: event.altKey,\n * }),\n * });\n *\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftAsyncProcesses(() => ({\n * handleShortcut: asyncProcess({\n * method: afterRecomputation(this.keydownSource, (data) => data),\n * loader: async ({ params }) => {\n * // Handle Ctrl+S\n * if (params.ctrlKey && params.key === 's') {\n * // Save action\n * return { action: 'save' };\n * }\n * // Handle Ctrl+Z\n * if (params.ctrlKey && params.key === 'z') {\n * // Undo action\n * return { action: 'undo' };\n * }\n * return null;\n * },\n * }),\n * }))\n * );\n *\n * store = this.injectCraft();\n * }\n * ```\n */\nexport function sourceFromEvent<T>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: never;\n source: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n debugName?: string;\n };\n },\n): SourceFromEvent<T>;\nexport function sourceFromEvent<T, ComputedValue>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue: (event: T) => ComputedValue;\n source?: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n debugName?: string;\n };\n },\n): SourceFromEvent<ComputedValue>;\nexport function sourceFromEvent(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: (event: Event) => unknown;\n source?: {\n equal?: ValueEqualityFn<NoInfer<unknown> | undefined>;\n debugName?: string;\n };\n },\n): SourceFromEvent<unknown> {\n assertInInjectionContext(sourceFromEvent);\n const eventSignalSource = signalSource<unknown>(options?.source);\n\n const listener = (event: Event) => {\n if (options?.computedValue) {\n const computed = options.computedValue(event);\n eventSignalSource.set(computed);\n return;\n }\n eventSignalSource.set(event);\n };\n\n target.addEventListener(eventName, listener, options?.event);\n\n const destroyRef = inject(DestroyRef);\n\n const dispose = () => {\n target.removeEventListener(eventName, listener, options?.event);\n };\n\n destroyRef.onDestroy(() => {\n dispose();\n });\n\n return Object.assign(eventSignalSource, {\n dispose,\n });\n}\n","import { linkedSignal, Signal, signal } from '@angular/core';\n\nexport type StackSource<T> = Signal<T[] | undefined> & {\n set: (value: T) => void;\n};\n\n// ! this algo only works with object\nexport function stackedSource<T>(): StackSource<T> {\n const stack: unknown[] = [];\n const s2 = signal<T | undefined>(undefined);\n\n const l = linkedSignal({\n source: s2,\n computation: (current, previousData) => {\n if (!previousData) {\n stack.length = 0;\n return undefined;\n }\n\n const result = [...stack];\n stack.length = 0;\n return result;\n },\n });\n\n const set = (value: T) => {\n console.log('custom set', value);\n stack.push(value);\n console.log('stack', stack);\n\n s2.set(value);\n return;\n };\n\n return Object.assign(l, {\n set,\n }) as StackSource<T>;\n}\n","import { isSignal, Signal, signal, WritableSignal } from '@angular/core';\nimport {\n InsertionsStateFactory,\n InsertionStateFactoryContext,\n} from './query.core';\nimport { MergeObject } from './util/types/util.type';\nimport { FilterSource, IsEmptyObject } from './util/util.type';\n\nexport type StateOutput<StateType, Insertions> = MergeObject<\n Signal<StateType>,\n IsEmptyObject<Insertions> extends true ? {} : FilterSource<Insertions>\n>;\n\ntype StateConfig<State> = State | WritableSignal<State>;\n\n/**\n * Creates a signal state with optional insertions for adding methods and computed properties.\n *\n * The `state` function allows you to create a Signal-based state that can be extended with custom\n * methods and properties through insertions. Each insertion receives a context object with\n * `state`, `set`, `update` methods and previous insertions.\n *\n * @param stateConfig - The initial state value or a WritableSignal (e.g., linkedSignal)\n * @param insertions - Optional insertion functions to extend the state with methods and properties\n * @returns A Signal representing the state, merged with all insertion properties and methods\n *\n * @example\n * // Simple state with a primitive value\n * const counter = state(0);\n * console.log(counter()); // 0\n *\n * @example\n * // State with a linkedSignal\n * const origin = signal(5);\n * const doubled = state(linkedSignal(() => origin() * 2));\n * console.log(doubled()); // 10\n *\n * @example\n * // State with insertions to add methods\n * const origin = signal(5);\n * const counter = state(\n * linkedSignal(() => origin() * 2),\n * ({ update, set }) => ({\n * increment: () => update((current) => current + 1),\n * reset: () => set(0),\n * })\n * );\n * console.log(counter()); // 10\n * counter.increment();\n * console.log(counter()); // 11\n * counter.reset();\n * console.log(counter()); // 0\n *\n * @example\n * // State with multiple insertions (methods and computed properties)\n * const origin = signal(5);\n * const counter = state(\n * linkedSignal(() => origin() * 2),\n * ({ update, set }) => ({\n * increment: () => update((current) => current + 1),\n * reset: () => set(0),\n * }),\n * ({ state }) => ({\n * isOdd: computed(() => state() % 2 === 1),\n * })\n * );\n * console.log(counter()); // 10\n * console.log(counter.isOdd()); // false\n * counter.increment();\n * console.log(counter()); // 11\n * console.log(counter.isOdd()); // true\n *\n * @example\n * // State with source binding (methods bound to sources are not exposed)\n * const sourceSignal = source<number>();\n * const myState = state(0, ({ set }) => ({\n * setValue: afterRecomputation(sourceSignal, (value) => set(value)),\n * reset: () => set(0),\n * }));\n * console.log(myState()); // 0\n * // Note: setValue is not exposed on myState, only used internally\n * sourceSignal.set(34);\n * console.log(myState()); // 34\n * myState.reset();\n * console.log(myState()); // 0\n */\nexport function state<StateType>(\n stateConfig: StateConfig<StateType>\n): StateOutput<StateType, {}>;\nexport function state<StateType, Insertion1>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>\n): StateOutput<StateType, Insertion1>;\nexport function state<StateType, Insertion1, Insertion2>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<NoInfer<StateType>, Insertion2, Insertion1>\n): StateOutput<StateType, Insertion1 & Insertion2>;\nexport function state<StateType, Insertion1, Insertion2, Insertion3>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >\n): StateOutput<StateType, Insertion1 & Insertion2 & Insertion3>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >\n): StateOutput<StateType, Insertion1 & Insertion2 & Insertion3 & Insertion4>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >\n): StateOutput<\n StateType,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >\n): StateOutput<\n StateType,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n>;\nexport function state<\n StateType,\n Insertion1,\n Insertion2,\n Insertion3,\n Insertion4,\n Insertion5,\n Insertion6,\n Insertion7\n>(\n stateConfig: StateConfig<StateType>,\n insertion1: InsertionsStateFactory<NoInfer<StateType>, Insertion1>,\n insertion2: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion2,\n Insertion1\n >,\n insertion3: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion3,\n Insertion1 & Insertion2\n >,\n insertion4: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion4,\n Insertion1 & Insertion2 & Insertion3\n >,\n insertion5: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion5,\n Insertion1 & Insertion2 & Insertion3 & Insertion4\n >,\n insertion6: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion6,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5\n >,\n insertion7: InsertionsStateFactory<\n NoInfer<StateType>,\n Insertion7,\n Insertion1 & Insertion2 & Insertion3 & Insertion4 & Insertion5 & Insertion6\n >\n): StateOutput<\n StateType,\n Insertion1 &\n Insertion2 &\n Insertion3 &\n Insertion4 &\n Insertion5 &\n Insertion6 &\n Insertion7\n>;\nexport function state<StateType>(\n stateConfig: StateConfig<StateType>,\n ...insertions: any[]\n): StateOutput<StateType, {}> {\n const isSignalState = isSignal(stateConfig);\n const stateSignal = isSignalState\n ? (stateConfig as WritableSignal<StateType>)\n : signal(stateConfig as StateType);\n\n return Object.assign(\n stateSignal,\n (insertions as InsertionsStateFactory<StateType, {}>[])?.reduce(\n (acc, insert) => {\n return {\n ...acc,\n ...insert({\n state: stateSignal.asReadonly(),\n set: (newState: StateType) => stateSignal.set(newState),\n update: (updateFn: (currentState: StateType) => StateType) =>\n stateSignal.update(updateFn),\n insertions: acc as {},\n } as InsertionStateFactoryContext<StateType, {}>),\n };\n },\n {} as Record<string, unknown>\n )\n ) as unknown as StateOutput<StateType, {}>;\n}\n","import {\n linkedSignal,\n Signal,\n untracked,\n ValueEqualityFn,\n WritableSignal,\n} from '@angular/core';\nimport { IsUnknown } from './util/util.type';\nimport { ReadonlySource } from './util/source.type';\nimport { SourceBranded } from './util/util';\n\n/**\n * Converts an Angular signal into a readonly source with lazy emission semantics.\n *\n * This function bridges the gap between signals and sources by:\n * - Converting continuous signal values into discrete source emissions\n * - Implementing lazy emission (only emits on signal changes, not on first read)\n * - Supporting optional value transformation via computed function\n * - Providing both standard and value-preserving listener variants\n * - Enabling signal-to-source conversions for event-driven architectures\n *\n * @remarks\n * **Signal vs Source Semantics:**\n * - **Signals**: Continuously readable, always have a value, recompute on access\n * - **Sources**: Emit only on explicit changes, lazy by default (undefined on first read)\n * - toSource converts continuous signal behavior to discrete source emissions\n *\n * **Emission Behavior:**\n * - First read returns `undefined` by default (maintains source lazy semantics)\n * - Subsequent reads return new values only when the origin signal changes\n * - Use `preserveLastValue` variant to get immediate value on first read\n *\n * **Use Cases:**\n * - **Event-driven patterns**: Convert signals to sources for reactive chains\n * - **Debounced signals**: Wrap debounced signals as sources for queries/mutations\n * - **External state**: Convert RxJS signals (toSignal) to sources\n * - **Form signals**: Convert form control signals to sources for automatic submission\n * - **Route params**: Convert router param signals to sources for automatic queries\n * - **Filtering**: Transform signal values while converting to source\n *\n * **Transformation:**\n * - Without `computed`: Passes signal values through unchanged\n * - With `computed`: Applies transformation before emitting to source\n * - Useful for extracting fields, formatting, or type narrowing\n *\n * **Comparison with computedSource:**\n * - `toSource`: Converts signals to sources (signal → source)\n * - `computedSource`: Transforms sources to sources (source → source)\n * - Use toSource when bridging from signal world to source world\n *\n * @template SourceState - The type of values from the origin signal\n * @template ComputedValue - The type of values after optional computation\n *\n * @param signalOrigin - The signal or writable signal to convert.\n * Changes to this signal trigger source emissions.\n *\n * @param options - Optional configuration:\n * - `computed`: Function to transform signal values before emission\n * - `equal`: Custom equality function for change detection\n * - `debugName`: Name for debugging purposes\n *\n * @returns A readonly source that emits when the signal changes with:\n * - Standard behavior: First read returns `undefined`, subsequent reads return values after signal changes\n * - `preserveLastValue` property: Returns current value immediately on first read\n *\n * @example\n * Basic signal to source conversion\n * ```ts\n * const countSignal = signal(0);\n * const countSource = toSource(countSignal);\n *\n * // Use in query for automatic execution\n * const fetchData = query({\n * method: afterRecomputation(countSource, (count) => count),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/data/${params}`);\n * return response.json();\n * },\n * });\n *\n * // Query executes when signal changes\n * countSignal.set(1);\n * // -> countSource emits 1\n * // -> fetchData executes with params 1\n *\n * countSignal.set(2);\n * // -> countSource emits 2\n * // -> fetchData executes with params 2\n * ```\n *\n * @example\n * Converting route params to source\n * ```ts\n * @Component({\n * selector: 'app-user-detail',\n * template: `...`,\n * })\n * export class UserDetailComponent {\n * route = inject(ActivatedRoute);\n *\n * // Convert route param to signal\n * userIdSignal = toSignal(\n * this.route.params.pipe(map(p => p['userId']))\n * );\n *\n * // Convert signal to source\n * userIdSource = toSource(this.userIdSignal);\n *\n * // Use source in query\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('user', () =>\n * query({\n * method: afterRecomputation(this.userIdSource, (id) => id),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * const response = await fetch(`/api/users/${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n *\n * // Query automatically updates when route changes\n * }\n * ```\n *\n * @example\n * Transforming signal values during conversion\n * ```ts\n * type FormData = {\n * name: string;\n * email: string;\n * preferences: { newsletter: boolean };\n * };\n *\n * const formSignal = signal<FormData>({\n * name: '',\n * email: '',\n * preferences: { newsletter: false },\n * });\n *\n * // Extract only email for validation\n * const emailSource = toSource(formSignal, {\n * computed: (form) => form.email,\n * });\n *\n * // Use in async method\n * const validateEmail = asyncProcess({\n * method: afterRecomputation(emailSource, (email) => email),\n * loader: async ({ params }) => {\n * if (!params) return null;\n * const response = await fetch('/api/validate-email', {\n * method: 'POST',\n * body: JSON.stringify({ email: params }),\n * });\n * return response.json();\n * },\n * });\n *\n * // Email validation triggers when form email changes\n * formSignal.update(form => ({ ...form, email: 'john@example.com' }));\n * // -> emailSource emits 'john@example.com'\n * // -> validateEmail executes\n * ```\n *\n * @example\n * Debounced signal to source\n * ```ts\n * const searchInputSignal = signal('');\n *\n * // Create debounced signal (using custom debounce logic)\n * const debouncedSearchSignal = computed(() => {\n * const input = searchInputSignal();\n * // Debounce logic would go here\n * return input;\n * });\n *\n * // Convert to source\n * const debouncedSearchSource = toSource(debouncedSearchSignal);\n *\n * // Use in query\n * const searchResults = query({\n * method: afterRecomputation(debouncedSearchSource, (term) => term),\n * loader: async ({ params }) => {\n * if (!params) return [];\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * });\n *\n * // Query executes only after debounce\n * searchInputSignal.set('ang');\n * searchInputSignal.set('angu');\n * searchInputSignal.set('angular');\n * // -> Eventually debouncedSearchSource emits 'angular'\n * // -> searchResults query executes once\n * ```\n *\n * @example\n * Form control signal to source\n * ```ts\n * @Component({\n * selector: 'app-search',\n * template: `\n * <input [formControl]=\"searchControl\" />\n * `,\n * })\n * export class SearchComponent {\n * searchControl = new FormControl('');\n *\n * // Convert form control value to signal\n * searchSignal = toSignal(\n * this.searchControl.valueChanges.pipe(\n * debounceTime(300),\n * distinctUntilChanged()\n * ),\n * { initialValue: '' }\n * );\n *\n * // Convert signal to source\n * searchSource = toSource(this.searchSignal);\n *\n * // Use in store\n * { injectCraft } = craft(\n * { name: '', providedIn: 'root' },\n * craftQuery('results', () =>\n * query({\n * method: afterRecomputation(this.searchSource, (term) => term),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * })\n * )\n * );\n *\n * store = this.injectCraft();\n * }\n * ```\n *\n * @example\n * Custom equality for change detection\n * ```ts\n * type SearchParams = { query: string; timestamp: number };\n *\n * const paramsSignal = signal<SearchParams>({\n * query: '',\n * timestamp: Date.now(),\n * });\n *\n * // Only emit when query changes, ignore timestamp\n * const querySource = toSource(paramsSignal, {\n * computed: (params) => params.query,\n * equal: (a, b) => a === b, // Compare strings only\n * });\n *\n * // Update with same query but different timestamp\n * paramsSignal.set({ query: 'test', timestamp: Date.now() });\n * // -> querySource emits 'test'\n *\n * paramsSignal.set({ query: 'test', timestamp: Date.now() });\n * // -> querySource does NOT emit (same query)\n *\n * paramsSignal.set({ query: 'new', timestamp: Date.now() });\n * // -> querySource emits 'new'\n * ```\n *\n * @example\n * Using preserveLastValue for immediate access\n * ```ts\n * const countSignal = signal(5);\n * const countSource = toSource(countSignal);\n *\n * // Standard behavior - first read is undefined\n * console.log(countSource()); // undefined\n *\n * countSignal.set(10);\n * console.log(countSource()); // 10\n *\n * // Using preserveLastValue - gets current value immediately\n * const immediateCount = countSource.preserveLastValue;\n * console.log(immediateCount()); // 10\n *\n * countSignal.set(15);\n * console.log(immediateCount()); // 15\n * ```\n *\n * @example\n * Complex transformation with validation\n * ```ts\n * type RawInput = { text: string; valid?: boolean };\n *\n * const inputSignal = signal<RawInput>({ text: '' });\n *\n * // Transform and validate during conversion\n * const validInputSource = toSource(inputSignal, {\n * computed: (input) => {\n * const trimmed = input.text.trim();\n * if (trimmed.length < 3) {\n * return null; // Invalid input\n * }\n * return {\n * text: trimmed.toLowerCase(),\n * length: trimmed.length,\n * };\n * },\n * });\n *\n * // Use in mutation\n * const submitInput = mutation({\n * method: afterRecomputation(validInputSource, (data) => data),\n * loader: async ({ params }) => {\n * if (!params) {\n * throw new Error('Invalid input');\n * }\n * const response = await fetch('/api/submit', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * // Invalid input\n * inputSignal.set({ text: 'ab' });\n * // -> validInputSource emits null\n * // -> submitInput throws error\n *\n * // Valid input\n * inputSignal.set({ text: 'Valid Input' });\n * // -> validInputSource emits { text: 'valid input', length: 11 }\n * // -> submitInput executes with transformed data\n * ```\n */\nexport function toSource<SourceState, ComputedValue>(\n signalOrigin: Signal<SourceState> | WritableSignal<SourceState>,\n options?: {\n computed?: (sourceValue: NoInfer<SourceState>) => ComputedValue;\n equal?: ValueEqualityFn<NoInfer<SourceState> | undefined>;\n debugName?: string;\n },\n): ReadonlySource<\n IsUnknown<ComputedValue> extends true ? SourceState : ComputedValue\n> {\n const sourceState = linkedSignal<SourceState | undefined>(signalOrigin, {\n ...(options?.equal && { equal: options?.equal }), // add the equal function here, it may helps to detect changes when using scalar values\n ...(options?.debugName && {\n debugName: options?.debugName + '_sourceState',\n }),\n });\n\n const listener = (listenerOptions: { nullishFirstValue?: boolean }) =>\n linkedSignal<SourceState, any>({\n source: sourceState as Signal<SourceState>,\n computation: (currentSourceState, previousData) => {\n // always when first listened return undefined\n if (!previousData && listenerOptions?.nullishFirstValue !== false) {\n return undefined;\n }\n //! use untracked to avoid computation to be re-evaluated when used inside another effect/computed\n return untracked(() =>\n options?.computed\n ? options?.computed?.(currentSourceState)\n : currentSourceState,\n );\n },\n ...(options?.equal && { equal: options?.equal }),\n ...(options?.debugName && { debugName: options?.debugName }),\n });\n return Object.assign(\n listener({\n nullishFirstValue: true,\n }),\n {\n preserveLastValue: listener({\n nullishFirstValue: false,\n }),\n },\n SourceBranded,\n ) as ReadonlySource<any>;\n}\n","import { EventEmitter, Type } from '@angular/core';\nimport { StoreConfigConstraints } from '../craft';\nimport { SignalSource } from '../signal-source';\nimport { ExtractSignalPropsAndMethods } from './extract-signal-props-and-methods';\nimport { ReadonlySource } from './source.type';\nimport { SourceBranded } from './util';\n\nexport type FilterPrivateFields<T> = {\n [K in keyof T as K extends `_${string}` ? never : K]: T[K];\n};\n\nexport type ToConnectableSourceFromInject<Sources> = {\n [K in keyof Sources]: Sources[K] extends SignalSource<infer SourceType>\n ? ReadonlySource<SourceType>\n : never;\n};\n\nexport type ToConnectableMethodFromInject<Methods> = RemoveIndexSignature<{\n [K in keyof Methods]?: Methods[K] extends (payload: infer Payload) => any\n ? IsUnknown<Payload> extends true\n ?\n | ReadonlySource<any>\n | {\n subscribe: EventEmitter<any>['subscribe'];\n }\n :\n | ReadonlySource<Payload>\n | {\n subscribe: EventEmitter<Payload>['subscribe'];\n }\n : never;\n}>;\n\nexport type IsUnknown<T> = unknown extends T\n ? [T] extends [unknown]\n ? true\n : false\n : false;\n\nexport type RemoveIndexSignature<T> = {\n [K in keyof T as string extends K\n ? never\n : number extends K\n ? never\n : symbol extends K\n ? never\n : K]: T[K];\n};\n\nexport type IsEmptyObject<T> = keyof T extends never ? true : false;\n\nexport type ExcludeCommonKeys<Origin, Target> = {\n [key in keyof Origin as key extends keyof Target ? never : key]: Origin[key];\n};\n\nexport const STORE_CONFIG_TOKEN = {\n NAME: '_STORE_NAME_',\n PROVIDED_IN: '_STORE_PROVIDED_IN_',\n} as const;\nexport type StoreConfigToken = typeof STORE_CONFIG_TOKEN;\n\nexport type ReplaceStoreConfigToken<\n StandaloneOutputName extends string,\n StoreConfig extends StoreConfigConstraints,\n> = StandaloneOutputName extends `${infer StoreNamePrefix}${typeof STORE_CONFIG_TOKEN.NAME}${infer StoreNameSuffix}`\n ? ReplaceStoreConfigToken<\n `${StoreNamePrefix}${Capitalize<StoreConfig['name']>}${StoreNameSuffix}`,\n StoreConfig\n >\n : StandaloneOutputName extends `${infer StoreProvidedInPrefix}${typeof STORE_CONFIG_TOKEN.PROVIDED_IN}${infer StoreProvidedInSuffix}`\n ? ReplaceStoreConfigToken<\n `${StoreProvidedInPrefix}${Capitalize<\n StoreConfig['providedIn']\n >}${StoreProvidedInSuffix}`,\n StoreConfig\n >\n : StandaloneOutputName;\n\nexport type FilterMethodsBoundToSources<\n Methods extends {},\n Rest,\n MethodPrefix extends string,\n MethodName extends string,\n Acc = {},\n> = Rest extends [infer First, ...infer Next]\n ? First extends keyof Methods\n ? Methods[First] extends {\n [Key in MethodName]: infer Method;\n }\n ? [Method] extends [ReadonlySource<infer SourceState>]\n ? FilterMethodsBoundToSources<\n Methods,\n Next,\n MethodPrefix,\n MethodName,\n Acc\n >\n : FilterMethodsBoundToSources<\n Methods,\n Next,\n MethodPrefix,\n MethodName,\n Acc & {\n [K in First as `${MethodPrefix}${Capitalize<string & K>}`]: [\n Method,\n ] extends [Function]\n ? Method\n : never;\n }\n >\n : FilterMethodsBoundToSources<\n Methods,\n Next,\n MethodPrefix,\n MethodName,\n Acc\n >\n : FilterMethodsBoundToSources<Methods, Next, MethodPrefix, MethodName, Acc>\n : Acc;\n\nexport type FilterSource<Insertions> = {\n [K in keyof Insertions as Insertions[K] extends SourceBranded\n ? never\n : K]: Insertions[K];\n};\n\n// Helper type to defer evaluation and avoid infinite recursion\nexport type DeferredExtract<Insertions> =\n UnionToTuple<keyof Insertions> extends infer Keys\n ? ExtractSignalPropsAndMethods<\n Insertions,\n Keys,\n { props: {}; methods: Record<string, Function> }\n >\n : never;\n\nexport type HasKeys<T> = T extends object\n ? keyof T extends never\n ? false\n : true\n : false;\ntype _FlatRecord<T> = T[keyof T] extends infer U\n ? { [K in keyof U]: U[K] }\n : never;\n\nexport type FlatRecord<T> = Prettify<UnionToIntersection<_FlatRecord<T>>>;\n\n// It is not possible to get all the properties key of an optional object, so make the optional properties required\nexport type MakeOptionalPropertiesRequired<\n T,\n K extends keyof T = keyof T,\n> = T & {\n [P in K]-?: T[P];\n};\n\nexport type MergeObject<A, B> = A & B;\n\nexport type MergeObjects<F extends unknown[], Acc = {}> = F extends [\n infer First,\n ...infer Rest,\n]\n ? First extends object\n ? MergeObjects<Rest, MergeObject<Acc, First>>\n : Prettify<Acc>\n : Prettify<Acc>;\n\n// from https://github.com/ecyrbe/zodios/blob/main/src/utils.types.ts\n/**\n * trick to combine multiple unions of objects into a single object\n * only works with objects not primitives\n * @param union - Union of objects\n * @returns Intersection of objects\n */\nexport type UnionToIntersection<union> = (\n union extends any ? (k: union) => void : never\n) extends (k: infer intersection) => void\n ? intersection\n : never;\n\n/**\n * get last element of union\n * @param Union - Union of any types\n * @returns Last element of union\n */\ntype GetUnionLast<Union> =\n UnionToIntersection<\n Union extends any ? () => Union : never\n > extends () => infer Last\n ? Last\n : never;\n\n/**\n * Convert union to tuple\n * @param Union - Union of any types, can be union of complex, composed or primitive types\n * @returns Tuple of each elements in the union\n */\nexport type UnionToTuple<Union, Tuple extends unknown[] = []> = [\n Union,\n] extends [never]\n ? Tuple\n : UnionToTuple<\n Exclude<Union, GetUnionLast<Union>>,\n [GetUnionLast<Union>, ...Tuple]\n >;\n\nexport type HasChild<T> = T extends any[]\n ? false\n : T extends object\n ? true\n : false;\n\nexport type OmitStrict<T, K extends keyof T> = T extends any\n ? Pick<T, Exclude<keyof T, K>>\n : never;\n\n/**\n * Negates a boolean type.\n */\nexport type Not<T extends boolean> = T extends true ? false : true;\n\n/**\n * @internal\n */\nconst secret = Symbol('secret');\n\n/**\n * @internal\n */\ntype Secret = typeof secret;\n\n/**\n * Checks if the given type is `never`.\n */\nexport type IsNever<T> = [T] extends [never] ? true : false;\n\nexport type IsAny<T> = [T] extends [Secret] ? Not<IsNever<T>> : false;\n\nexport type InferInjectedType<T extends Type<unknown>> =\n T extends Type<infer U> ? U : never;\n\nexport type Prettify<T> = {\n [K in keyof T]: T[K];\n} & {};\n","// todo handle update of array of objects\nexport function createNestedStateUpdate({\n state,\n keysPath,\n value,\n}: {\n state: any;\n keysPath: string[];\n value: any;\n}): any {\n if (keysPath.length === 0) {\n return value;\n }\n\n const [currentKey, ...remainingKeys] = keysPath;\n const currentState = state[currentKey] || {};\n\n return {\n ...state,\n [currentKey]:\n remainingKeys.length === 0\n ? Array.isArray(currentState)\n ? value\n : typeof value === 'object' && value !== null && !Array.isArray(value)\n ? { ...currentState, ...value }\n : value\n : createNestedStateUpdate({\n state: currentState,\n keysPath: remainingKeys,\n value,\n }),\n };\n}\nexport function getNestedStateValue({\n state,\n keysPath,\n}: {\n state: any;\n keysPath: string[];\n}): any {\n return keysPath.reduce((currentState, key) => {\n if (currentState && typeof currentState === 'object') {\n return currentState[key];\n }\n return undefined;\n }, state);\n}\n","import { ResourceStatus, Signal, WritableSignal } from '@angular/core';\nimport {\n CustomReloadOnSpecificMutationStatus,\n FilterQueryById,\n PatchQueryFn,\n PatchMutationQuery,\n QueryAndMutationRecordConstraints,\n ReloadQueriesConfig,\n} from './util/types/shared.type';\nimport { ResourceByIdRef } from './resource-by-id';\nimport {\n getNestedStateValue,\n createNestedStateUpdate,\n} from './util/update-state.util';\nimport { MergeObjects } from './util//types/util.type';\nimport {\n ResourceByIdLikeMutationRef,\n ResourceLikeMutationRef,\n} from './mutation';\nimport { CraftResourceRef } from './util/craft-resource-ref';\nimport { QueryParamsToState } from './query-param';\nimport { Prettify } from './util/util.type';\n\nexport interface QueryParamNavigationOptions {\n queryParamsHandling?: 'merge' | 'preserve' | '';\n onSameUrlNavigation?: 'reload' | 'ignore';\n replaceUrl?: boolean;\n skipLocationChange?: boolean;\n}\n\nexport type MutationResourceRefHelper<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = ResourceLikeMutationRef<\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params'],\n QueryAndMutationRecord['mutation']['isMethod'],\n QueryAndMutationRecord['mutation']['args'],\n QueryAndMutationRecord['mutation']['sourceParams'],\n QueryAndMutationRecord['mutation']['insertions']\n>;\n\nexport type MutationResourceByIdRefHelper<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = ResourceByIdLikeMutationRef<\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params'],\n QueryAndMutationRecord['mutation']['isMethod'],\n QueryAndMutationRecord['mutation']['args'],\n QueryAndMutationRecord['mutation']['sourceParams'],\n QueryAndMutationRecord['mutation']['insertions'],\n QueryAndMutationRecord['mutation']['groupIdentifier']\n>;\n\ntype UpdateData<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = MergeObjects<\n [\n {\n queryResource: CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationResource: CraftResourceRef<\n NoInfer<QueryAndMutationRecord['mutation']['state']>,\n NoInfer<QueryAndMutationRecord['mutation']['params']>\n >;\n mutationParams: NonNullable<\n NoInfer<QueryAndMutationRecord['mutation']['params']>\n >;\n },\n QueryAndMutationRecord['query']['isGroupedResource'] extends true\n ? {\n queryIdentifier: QueryAndMutationRecord['query']['groupIdentifier'];\n queryResources: ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n }\n : {},\n QueryAndMutationRecord['mutation']['groupIdentifier'] extends\n | string\n | number\n ? {\n mutationIdentifier: QueryAndMutationRecord['mutation']['groupIdentifier'];\n mutationResources: ResourceByIdRef<\n string,\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params']\n >;\n }\n : {},\n ]\n>;\n\nexport type QueryDeclarativeEffect<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n> = MergeObjects<\n [\n {\n /**\n * Run when the mutation is in loading state.\n */\n optimisticUpdate?: (\n data: UpdateData<QueryAndMutationRecord> & {\n testData: QueryAndMutationRecord['query']['groupIdentifier'];\n },\n ) => QueryAndMutationRecord['query']['state'];\n /**\n * Run when the mutation is in loaded state.\n */\n update?: (\n data: UpdateData<QueryAndMutationRecord>,\n ) => QueryAndMutationRecord['query']['state'];\n reload?: ReloadQueriesConfig<QueryAndMutationRecord>;\n /**\n * Run when the mutation is in loading state.\n * Will patch the query specific state with the mutation data.\n * If the query is loading, it will not patch.\n * If the mutation data is not compatible with the query state, it will not patch.\n * Be careful! If the mutation is already in a loading state, trigger the mutation again will cancelled the previous mutation loader and will patch with the new value.\n */\n optimisticPatch?: PatchMutationQuery<QueryAndMutationRecord>;\n /**\n * Run when the mutation is in loaded state.\n * Will patch the query specific state with the mutation data.\n * If the query is loading, it will not patch.\n * If the mutation data is not compatible with the query state, it will not patch.\n * Be careful! If the mutation is already in a loading state, trigger the mutation again will cancelled the previous mutation loader and will patch with the new value.\n */\n patch?: PatchMutationQuery<QueryAndMutationRecord>;\n },\n QueryAndMutationRecord['mutation']['isGroupedResource'] extends true\n ? {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n : QueryAndMutationRecord['query']['isGroupedResource'] extends true\n ? {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n : {},\n ]\n>;\n\nexport function triggerQueryReloadFromMutationChange<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n reload,\n mutationStatus,\n queryResource,\n mutationResource,\n mutationParamsSrc,\n queryIdentifier,\n queryResources,\n mutationIdentifier,\n mutationResources,\n}: {\n reload: ReloadQueriesConfig<QueryAndMutationRecord>;\n mutationStatus: string;\n queryResource: CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n queryResources:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | undefined;\n mutationResource: CraftResourceRef<any, any>;\n mutationParamsSrc: Signal<\n QueryAndMutationRecord['mutation']['params'] | undefined\n >;\n queryIdentifier: QueryAndMutationRecord['query']['groupIdentifier'];\n mutationIdentifier: QueryAndMutationRecord['mutation']['groupIdentifier'];\n mutationResources: ResourceByIdRef<string, any, unknown> | undefined;\n}) {\n const statusMappings = {\n onMutationError: 'error',\n onMutationResolved: 'resolved',\n onMutationLoading: 'loading',\n };\n\n Object.entries(reload).forEach(([reloadType, reloadConfig]) => {\n const expectedStatus =\n statusMappings[reloadType as keyof typeof statusMappings];\n\n if (expectedStatus && mutationStatus === expectedStatus) {\n if (typeof reloadConfig === 'function') {\n if (\n reloadConfig({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n mutationIdentifier,\n mutationResources,\n queryResources,\n })\n ) {\n queryResource.reload();\n }\n } else if (reloadConfig) {\n queryResource.reload();\n }\n }\n });\n}\n\nexport function triggerQueryReloadOnMutationStatusChange<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n mutationStatus,\n queryResourceTarget,\n mutationEffectOptions,\n mutationResource,\n mutationParamsSrc,\n reloadCConfig,\n mutationIdentifier,\n mutationResources,\n}: {\n mutationStatus: string;\n queryResourceTarget:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationEffectOptions: QueryDeclarativeEffect<QueryAndMutationRecord>;\n mutationResource: CraftResourceRef<any, any>;\n mutationParamsSrc: Signal<QueryAndMutationRecord['mutation']['params']>;\n reloadCConfig: {\n onMutationError?:\n | boolean\n | CustomReloadOnSpecificMutationStatus<QueryAndMutationRecord>;\n onMutationResolved?:\n | boolean\n | CustomReloadOnSpecificMutationStatus<QueryAndMutationRecord>;\n onMutationLoading?:\n | boolean\n | CustomReloadOnSpecificMutationStatus<QueryAndMutationRecord>;\n };\n mutationIdentifier:\n | QueryAndMutationRecord['mutation']['groupIdentifier']\n | undefined;\n mutationResources:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params']\n >\n | undefined;\n}) {\n if (\n (['error', 'loading', 'resolved'] satisfies ResourceStatus[]).includes(\n mutationStatus as any,\n )\n ) {\n if ('hasValue' in queryResourceTarget) {\n const queryResource = queryResourceTarget;\n triggerQueryReloadFromMutationChange({\n reload: reloadCConfig,\n mutationStatus,\n queryResource,\n mutationResource,\n mutationParamsSrc,\n queryIdentifier: undefined,\n mutationIdentifier,\n mutationResources,\n queryResources: undefined,\n });\n return;\n }\n const queryResourcesById = queryResourceTarget as ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n Object.entries(\n queryResourcesById() as Record<string, CraftResourceRef<any, any>>,\n )\n .filter(([queryIdentifier, queryResource]) => {\n return (\n mutationEffectOptions as {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n ).filter({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourceTarget,\n mutationIdentifier,\n mutationResources,\n } as any);\n })\n .forEach(([queryIdentifier, queryResource]) => {\n triggerQueryReloadFromMutationChange({\n reload: reloadCConfig,\n mutationStatus,\n queryResource,\n mutationResource,\n mutationParamsSrc,\n queryIdentifier,\n mutationIdentifier,\n mutationResources,\n queryResources: queryResourceTarget,\n });\n });\n }\n}\n\nexport function setAllPatchFromMutationOnQueryValue<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n mutationStatus,\n queryResourceTarget,\n mutationEffectOptions,\n mutationResource,\n mutationParamsSrc,\n mutationIdentifier,\n mutationResources,\n}: {\n mutationStatus: string;\n queryResourceTarget:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationEffectOptions: QueryDeclarativeEffect<QueryAndMutationRecord>;\n mutationResource: CraftResourceRef<any, any>;\n mutationParamsSrc: Signal<QueryAndMutationRecord['mutation']['params']>;\n mutationIdentifier:\n | QueryAndMutationRecord['mutation']['groupIdentifier']\n | undefined;\n mutationResources:\n | MutationResourceByIdRefHelper<QueryAndMutationRecord>\n | undefined;\n}) {\n if (mutationStatus !== 'loading' && mutationStatus !== 'resolved') {\n return;\n }\n const patchTarget =\n mutationStatus === 'loading'\n ? mutationEffectOptions.optimisticPatch\n : mutationEffectOptions.patch;\n if (!patchTarget) {\n return;\n }\n if ('hasValue' in queryResourceTarget) {\n const queryResource = queryResourceTarget;\n Object.entries(\n patchTarget as Record<string, PatchQueryFn<any, any>>,\n ).forEach(([path, optimisticPatch]) => {\n const queryValue = queryResource.hasValue()\n ? queryResource.value()\n : undefined;\n const optimisticValue = optimisticPatch({\n mutationResource,\n queryResource,\n queryResources: undefined,\n queryIdentifier: undefined,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n targetedState: getNestedStateValue({\n state: queryValue,\n keysPath: path.split('.'),\n }),\n mutationIdentifier,\n mutationResources,\n });\n const updatedValue = createNestedStateUpdate({\n state: queryValue,\n keysPath: path.split('.'),\n value: optimisticValue,\n });\n queryResource.set(updatedValue);\n });\n return;\n }\n const queryResourcesById = queryResourceTarget as ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n Object.entries(\n queryResourcesById() as Record<string, CraftResourceRef<any, any>>,\n )\n .filter(([queryIdentifier, queryResource]) =>\n (\n mutationEffectOptions as {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n ).filter({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourcesById,\n mutationIdentifier,\n mutationResources,\n } as any),\n )\n .forEach(([queryIdentifier, queryResource]) => {\n Object.entries(\n patchTarget as Record<string, PatchQueryFn<any, any>>,\n ).forEach(([path, patch]) => {\n const queryValue = queryResource.hasValue()\n ? queryResource.value()\n : undefined;\n const optimisticValue = patch({\n mutationResource,\n queryResource,\n queryResources: queryResourcesById,\n queryIdentifier,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n targetedState: getNestedStateValue({\n state: queryValue,\n keysPath: path.split('.'),\n }),\n mutationIdentifier,\n mutationResources,\n });\n const updatedValue = createNestedStateUpdate({\n state: queryValue,\n keysPath: path.split('.'),\n value: optimisticValue,\n });\n queryResource.set(updatedValue);\n });\n });\n}\n\nexport function setAllUpdatesFromMutationOnQueryValue<\n QueryAndMutationRecord extends QueryAndMutationRecordConstraints,\n>({\n mutationStatus,\n queryResourceTarget,\n mutationEffectOptions,\n mutationResource,\n mutationParamsSrc,\n mutationIdentifier,\n mutationResources,\n}: {\n mutationStatus: string;\n queryResourceTarget:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >\n | CraftResourceRef<\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n mutationEffectOptions: QueryDeclarativeEffect<QueryAndMutationRecord>;\n mutationResource: CraftResourceRef<any, any> | undefined;\n mutationParamsSrc: Signal<QueryAndMutationRecord['mutation']['params']>;\n mutationIdentifier:\n | QueryAndMutationRecord['mutation']['groupIdentifier']\n | undefined;\n mutationResources:\n | ResourceByIdRef<\n string,\n QueryAndMutationRecord['mutation']['state'],\n QueryAndMutationRecord['mutation']['params']\n >\n | undefined;\n}) {\n if (mutationStatus !== 'loading' && mutationStatus !== 'resolved') {\n return;\n }\n const updateTarget =\n mutationStatus === 'loading'\n ? mutationEffectOptions.optimisticUpdate\n : mutationEffectOptions.update;\n if (!updateTarget) {\n return;\n }\n\n if ('hasValue' in queryResourceTarget) {\n const queryResource = queryResourceTarget;\n const updatedValue = updateTarget({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier: undefined,\n queryResources: undefined,\n mutationIdentifier,\n mutationResources,\n } as any);\n queryResource.set(updatedValue);\n return;\n }\n const queryResourceById = queryResourceTarget as ResourceByIdRef<\n string,\n QueryAndMutationRecord['query']['state'],\n QueryAndMutationRecord['query']['params']\n >;\n Object.entries(\n queryResourceById() as Record<string, CraftResourceRef<any, any>>,\n )\n .filter(([queryIdentifier, queryResource]) =>\n (\n mutationEffectOptions as {\n filter: FilterQueryById<QueryAndMutationRecord>;\n }\n ).filter({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourceTarget,\n mutationIdentifier,\n mutationResources,\n } as any),\n )\n .forEach(([queryIdentifier, queryResource]) => {\n const updatedValue = updateTarget({\n queryResource,\n mutationResource,\n //@ts-expect-error the mutationParamsSrc depends if fromResourceById is used, this typing part can be improved\n mutationParams: mutationParamsSrc(mutationResource),\n queryIdentifier,\n queryResources: queryResourceTarget,\n mutationIdentifier,\n mutationResources,\n } as any);\n queryResource.set(updatedValue);\n });\n}\n\nexport type InsertionParams<\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n> = {\n state: Signal<ResourceState>;\n set: (newState: ResourceState) => ResourceState;\n update: (\n updateFn: (currentState: ResourceState) => ResourceState,\n ) => ResourceState;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n resource: CraftResourceRef<ResourceState, ResourceParams>;\n resourceParamsSrc: WritableSignal<ResourceParams | undefined>;\n // 👇 Seems required for insertLocalStoragePersister, otherwise TS says they can be missing\n resourceById: never;\n identifier: never;\n};\n\nexport type InsertionsFactory<\n ResourceState extends object | undefined,\n ResourceParams,\n InsertsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionParams<\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >,\n) => InsertsOutputs;\n\nexport type InsertionByIdParams<\n GroupIdentifier extends string,\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n> = {\n state: Signal<ResourceState>;\n set: (newState: ResourceState) => ResourceState;\n update: (\n updateFn: (currentState: ResourceState) => ResourceState,\n ) => ResourceState;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n resourceById: ResourceByIdRef<GroupIdentifier, ResourceState, ResourceParams>;\n resource: never;\n resourceParamsSrc: WritableSignal<ResourceParams | undefined>;\n identifier: (params: NonNullable<ResourceParams>) => GroupIdentifier;\n};\n\nexport type InsertionStateFactoryContext<StateType, PreviousInsertionsOutputs> =\n {\n state: Signal<StateType>;\n set: (newState: StateType) => StateType;\n update: (updateFn: (currentState: StateType) => StateType) => StateType;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n };\n\nexport type QueryParamMethods<QueryParamsState> = {\n patch: (\n params: Partial<QueryParamsState>,\n options?: QueryParamNavigationOptions,\n ) => void;\n reset: (options?: QueryParamNavigationOptions) => void;\n set: (\n params: QueryParamsState,\n options?: QueryParamNavigationOptions,\n ) => QueryParamsState;\n update: (\n updateFn: (currentParams: QueryParamsState) => QueryParamsState,\n options?: QueryParamNavigationOptions,\n ) => QueryParamsState;\n};\n\nexport type InsertionQueryParamsFactoryContext<\n QueryParamsType,\n PreviousInsertionsOutputs,\n //! do not get the QueryParamState directly from the queryParam utility (it's broke the inference),\n QueryParamsState = Prettify<QueryParamsToState<QueryParamsType>>,\n> = QueryParamMethods<QueryParamsState> & {\n state: Signal<QueryParamsState>;\n config: QueryParamsType;\n insertions: keyof PreviousInsertionsOutputs extends string\n ? PreviousInsertionsOutputs\n : never;\n};\n\nexport type InsertionsByIdFactory<\n ResourceState extends object | undefined,\n ResourceParams,\n GroupIdentifier extends string,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionByIdParams<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >,\n) => InsertionsOutputs;\n\nexport type InsertionResourceFactoryContext<\n GroupIdentifier,\n ResourceState extends object | undefined,\n ResourceParams,\n PreviousInsertionsOutputs,\n> = [unknown] extends [GroupIdentifier]\n ? InsertionParams<ResourceState, ResourceParams, PreviousInsertionsOutputs>\n : InsertionByIdParams<\n GroupIdentifier & string,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >;\nexport type InsertionsResourcesFactory<\n GroupIdentifier,\n ResourceState extends object | undefined,\n ResourceParams,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionResourceFactoryContext<\n GroupIdentifier,\n ResourceState,\n ResourceParams,\n PreviousInsertionsOutputs\n >,\n) => InsertionsOutputs;\n\nexport type InsertionsStateFactory<\n State,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionStateFactoryContext<State, PreviousInsertionsOutputs>,\n) => InsertionsOutputs;\n\nexport type InsertionsQueryParamsFactory<\n QueryParamsType,\n InsertionsOutputs,\n PreviousInsertionsOutputs = {},\n> = (\n context: InsertionQueryParamsFactoryContext<\n QueryParamsType,\n PreviousInsertionsOutputs\n >,\n) => InsertionsOutputs;\n\nexport type DefaultInsertionByIdParams = InsertionByIdParams<\n string,\n {},\n unknown,\n {}\n>;\n\nexport type DefaultInsertionParams = InsertionParams<{}, unknown, unknown>;\n","import {\n ResourceRef,\n Injector,\n effect,\n untracked,\n linkedSignal,\n Signal,\n inject,\n computed,\n} from '@angular/core';\nimport {\n ResourceLikeMutationRef,\n ResourceByIdLikeMutationRef,\n} from '../mutation';\nimport {\n QueryDeclarativeEffect,\n setAllUpdatesFromMutationOnQueryValue,\n triggerQueryReloadOnMutationStatusChange,\n setAllPatchFromMutationOnQueryValue,\n} from '../query.core';\nimport { ResourceByIdRef } from '../resource-by-id';\nimport { explicitNestedEffect } from './types/util';\nimport { InternalType } from './types/util.type';\nimport { ResourceByIdLikeQueryRef, ResourceLikeQueryRef } from '../query';\nimport { CraftResourceRef } from './craft-resource-ref';\n\n// todo improve internal function types\nexport function reactOnMutationEffect<\n QueryResourceState,\n QueryResourceParams,\n QueryResourceArgsParams,\n QueryIsMethod extends boolean,\n QuerySourceParams,\n QueryGroupIdentifier,\n QueryInsertions,\n MutationResourceState,\n MutationResourceParams,\n MutationResourceArgsParams,\n MutationIsMethod,\n MutationSourceParams,\n MutationGroupIdentifier,\n MutationInsertions,\n>(\n {\n queryTargeted,\n mutationTargeted,\n }: {\n queryTargeted:\n | ResourceLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions\n >\n | ResourceByIdLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions,\n QueryGroupIdentifier\n >;\n mutationTargeted:\n | ResourceLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions\n >\n | ResourceByIdLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions,\n MutationGroupIdentifier\n >;\n },\n mutationEffectOptions: QueryDeclarativeEffect<{\n query: InternalType<\n NoInfer<QueryResourceState>,\n NoInfer<QueryResourceParams>,\n NoInfer<QueryResourceArgsParams>,\n [unknown] extends [NoInfer<QueryGroupIdentifier>] ? false : true,\n NoInfer<QueryIsMethod>,\n NoInfer<QueryInsertions>,\n NoInfer<QueryGroupIdentifier>,\n NoInfer<QuerySourceParams>\n >;\n mutation: InternalType<\n NoInfer<MutationResourceState>,\n NoInfer<MutationResourceParams>,\n NoInfer<MutationResourceArgsParams>,\n [unknown] extends [MutationGroupIdentifier] ? false : true,\n NoInfer<MutationIsMethod>,\n NoInfer<MutationInsertions>,\n NoInfer<MutationGroupIdentifier>,\n NoInfer<MutationSourceParams>\n >;\n }>,\n) {\n const _injector = inject(Injector);\n if (mutationTargeted.type === 'resourceLike') {\n const mutationResource = mutationTargeted;\n return effect(() => {\n const mutationStatus = mutationResource.status();\n const mutationParamsSrc = mutationTargeted.resourceParamsSrc;\n // use to track the value of the mutation\n const _mutationValueChanged = mutationResource.hasValue()\n ? mutationResource.value()\n : undefined;\n\n if (\n mutationEffectOptions?.optimisticUpdate ||\n mutationEffectOptions.update\n ) {\n untracked(() => {\n setAllUpdatesFromMutationOnQueryValue({\n mutationStatus,\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions,\n mutationResource: mutationResource as any,\n mutationParamsSrc,\n mutationIdentifier: undefined,\n mutationResources: undefined,\n } as any);\n });\n }\n const reloadCConfig = mutationEffectOptions.reload;\n if (reloadCConfig) {\n untracked(() => {\n triggerQueryReloadOnMutationStatusChange({\n mutationStatus,\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource: mutationResource as unknown as ResourceRef<any>,\n mutationParamsSrc,\n reloadCConfig,\n mutationIdentifier: undefined,\n mutationResources: undefined,\n } as any);\n });\n }\n if (\n mutationEffectOptions.optimisticPatch ||\n mutationEffectOptions.patch\n ) {\n untracked(() => {\n setAllPatchFromMutationOnQueryValue({\n mutationStatus,\n //@ts-expect-error not understand from where the error come from\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource: mutationResource as unknown as CraftResourceRef<\n any,\n any\n >,\n mutationParamsSrc,\n mutationIdentifier: undefined,\n mutationResources: undefined,\n });\n });\n }\n });\n }\n const mutationResources = mutationTargeted._resourceById;\n\n const newMutationResourceRefForNestedEffect = linkedSignal<\n ResourceByIdRef<\n MutationGroupIdentifier & string,\n MutationResourceState,\n MutationResourceParams\n >,\n { newKeys: QueryGroupIdentifier[] } | undefined\n >({\n //@ts-expect-error I do not understand why it is not satisfies\n source: mutationResources,\n computation: (currentSource, previous) => {\n if (!currentSource || !Object.keys(currentSource).length) {\n return undefined;\n }\n\n const currentKeys = Object.keys(currentSource) as QueryGroupIdentifier[];\n const previousKeys = Object.keys(\n previous?.source || {},\n ) as QueryGroupIdentifier[];\n\n // Find keys that exist in current but not in previous\n const newKeys = currentKeys.filter((key) => !previousKeys.includes(key));\n\n return newKeys.length > 0 ? { newKeys } : previous?.value;\n },\n }) as unknown as Signal<{ newKeys: MutationGroupIdentifier[] } | undefined>;\n\n return effect(() => {\n if (!newMutationResourceRefForNestedEffect()?.newKeys) {\n return;\n }\n newMutationResourceRefForNestedEffect()?.newKeys.forEach(\n (mutationIdentifier) => {\n const mutationResource =\n mutationResources()[\n mutationIdentifier as MutationGroupIdentifier & string\n ];\n if (!mutationResource) {\n return;\n }\n const safeMutationResourceValue = computed(() =>\n mutationResource.hasValue()\n ? mutationResource.value()\n : (undefined as unknown as MutationResourceState),\n );\n explicitNestedEffect(\n _injector,\n [\n mutationResource.status,\n safeMutationResourceValue,\n mutationResource.paramSrc,\n ],\n ([mutationStatus, _value]) => {\n const mutationParamsSrc = mutationResource.paramSrc;\n if (\n typeof mutationParamsSrc === 'function' &&\n mutationParamsSrc()\n ) {\n // ! keep this check, it is used to track mutationParamsSrc, otherwise it does not works\n }\n if (\n mutationEffectOptions?.optimisticUpdate ||\n mutationEffectOptions.update\n ) {\n untracked(() => {\n setAllUpdatesFromMutationOnQueryValue({\n mutationStatus,\n queryResourceTarget: queryTargeted as any,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource,\n mutationParamsSrc,\n mutationIdentifier,\n mutationResources:\n mutationResources as unknown as ResourceByIdRef<\n string,\n any,\n any\n >,\n });\n });\n }\n const reloadCConfig = mutationEffectOptions.reload;\n if (reloadCConfig) {\n untracked(() => {\n triggerQueryReloadOnMutationStatusChange({\n mutationStatus,\n queryResourceTarget: queryTargeted,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource,\n mutationParamsSrc,\n reloadCConfig,\n mutationIdentifier,\n mutationResources:\n mutationResources as unknown as ResourceByIdRef<\n string,\n any,\n any\n >,\n } as any);\n });\n }\n if (\n mutationEffectOptions.optimisticPatch ||\n mutationEffectOptions.patch\n ) {\n untracked(() => {\n setAllPatchFromMutationOnQueryValue({\n mutationStatus,\n queryResourceTarget: queryTargeted as any,\n mutationEffectOptions: mutationEffectOptions as any,\n mutationResource:\n mutationResource as unknown as CraftResourceRef<any, any>,\n mutationParamsSrc,\n mutationIdentifier: mutationIdentifier,\n mutationResources: mutationTargeted as any,\n });\n });\n }\n },\n );\n },\n );\n });\n}\n","import { WritableSignal } from '@angular/core';\nimport {\n ResourceByIdLikeMutationRef,\n ResourceLikeMutationRef,\n} from './mutation';\nimport { ResourceByIdLikeQueryRef, ResourceLikeQueryRef } from './query';\nimport { InsertionParams, QueryDeclarativeEffect } from './query.core';\nimport { ResourceByIdRef } from './resource-by-id';\nimport { reactOnMutationEffect } from './util/react-on-mutation-effect';\nimport { InternalType } from './util/types/util.type';\n\n/**\n * Creates an insertion function that makes a query react to mutation state changes.\n *\n * This insertion enables declarative synchronization between queries and mutations, allowing you to:\n * - Optimistically update query data when a mutation starts (before server response)\n * - Update query data when a mutation completes successfully\n * - Patch specific fields in query data based on mutation parameters\n * - Reload queries when mutations complete\n * - Filter which query instances should react (when using identifiers)\n *\n * @remarks\n * This is particularly useful for:\n * - **Optimistic UI updates**: Show changes immediately while the mutation is processing\n * - **Cache synchronization**: Keep local query cache in sync with server state after mutations\n * - **Selective updates**: Update only relevant query instances based on identifiers\n * - **Complex state management**: Coordinate multiple queries reacting to the same mutation\n *\n * @param mutation - The mutation to react to. Can be either:\n * - A standard mutation (ResourceLikeMutationRef)\n * - A mutation with identifier for grouped instances (ResourceByIdLikeMutationRef)\n * @param mutationEffectOptions - Configuration for how the query should react:\n * - `optimisticUpdate`: Function to update query state immediately when mutation starts (loading state)\n * - `update`: Function to update query state when mutation completes (resolved state)\n * - `optimisticPatch`: Object mapping query fields to mutation values for optimistic updates\n * - `patch`: Object mapping query fields to mutation values for final updates\n * - `reload`: Configuration to reload the query when mutation reaches specific states\n * - `filter`: Function to determine which query instances should react (required when using identifiers)\n *\n * @returns An insertion function that can be passed to query() to enable the reactive behavior\n *\n * @example\n * Basic optimistic update with patch\n * ```ts\n * const updateUserMutation = mutation({\n * method: (data: { id: string; name: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * const userQuery = query(\n * {\n * params: () => ({ userId: currentUserId() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updateUserMutation, {\n * // Optimistically update the name while mutation is loading\n * optimisticPatch: {\n * name: ({ mutationParams }) => mutationParams.name,\n * },\n * // Apply final update when mutation resolves\n * patch: {\n * name: ({ mutationParams }) => mutationParams.name,\n * },\n * })\n * );\n *\n * // When mutation is triggered, query updates immediately (optimistic)\n * updateUserMutation.mutate({ id: '123', name: 'New Name' });\n * // userQuery.value().name is now 'New Name' (optimistic)\n *\n * // When mutation completes, patch confirms the change\n * // userQuery.value().name remains 'New Name' (confirmed)\n * ```\n *\n * @example\n * Full state update on mutation completion\n * ```ts\n * const deleteTodoMutation = mutation({\n * method: (todoId: string) => ({ todoId }),\n * loader: async ({ params }) => {\n * await fetch(`/api/todos/${params.todoId}`, { method: 'DELETE' });\n * return { deleted: true };\n * },\n * });\n *\n * const todosQuery = query(\n * {\n * params: () => ({}),\n * loader: async () => {\n * const response = await fetch('/api/todos');\n * return response.json(); // Returns Todo[]\n * },\n * },\n * insertReactOnMutation(deleteTodoMutation, {\n * // Remove the deleted todo from the list optimistically\n * optimisticUpdate: ({ queryResource, mutationParams }) => {\n * const currentTodos = queryResource.value() ?? [];\n * return currentTodos.filter(todo => todo.id !== mutationParams.todoId);\n * },\n * // Confirm the deletion when mutation resolves\n * update: ({ queryResource, mutationParams }) => {\n * const currentTodos = queryResource.value() ?? [];\n * return currentTodos.filter(todo => todo.id !== mutationParams.todoId);\n * },\n * })\n * );\n * ```\n *\n * @example\n * Reload query after mutation\n * ```ts\n * const createPostMutation = mutation({\n * method: (data: { title: string; content: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch('/api/posts', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * const postsQuery = query(\n * {\n * params: () => ({ page: 1 }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts?page=${params.page}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(createPostMutation, {\n * // Reload the posts list when mutation completes\n * reload: {\n * onMutationResolved: true, // Reload on success\n * },\n * })\n * );\n *\n * // When mutation completes, postsQuery automatically reloads\n * createPostMutation.mutate({ title: 'New Post', content: 'Content' });\n * ```\n *\n * @example\n * Filtered updates with identifiers\n * ```ts\n * const updatePostMutation = mutation({\n * method: (data: { postId: string; title: string }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts/${params.postId}`, {\n * method: 'PATCH',\n * body: JSON.stringify(params),\n * });\n * return response.json();\n * },\n * });\n *\n * const postsQuery = query(\n * {\n * params: () => currentPostId(),\n * identifier: (params) => params, // params is the postId\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/posts/${params}`);\n * return response.json();\n * },\n * },\n * insertReactOnMutation(updatePostMutation, {\n * // Only update the query instance that matches the mutation's postId\n * filter: ({ queryIdentifier, mutationParams }) =>\n * queryIdentifier === mutationParams.postId,\n * patch: {\n * title: ({ mutationParams }) => mutationParams.title,\n * },\n * })\n * );\n *\n * // Only the query instance for post '123' will be updated\n * updatePostMutation.mutate({ postId: '123', title: 'Updated Title' });\n * console.log(postsQuery.select('123')?.value()?.title); // 'Updated Title'\n * console.log(postsQuery.select('456')?.value()?.title); // unchanged\n * ```\n *\n * @example\n * Complex nested field updates\n * ```ts\n * const updateUserProfileMutation = mutation({\n * method: (data: { userId: string; profile: { bio: string; avatar: string } }) => data,\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}/profile`, {\n * method: 'PATCH',\n * body: JSON.stringify(params.profile),\n * });\n * return response.json();\n * },\n * });\n *\n * const userQuery = query(\n * {\n * params: () => ({ userId: currentUserId() }),\n * loader: async ({ params }) => {\n * const response = await fetch(`/api/users/${params.userId}`);\n * return response.json(); // Returns { id, name, profile: { bio, avatar, ... } }\n * },\n * },\n * insertReactOnMutation(updateUserProfileMutation, {\n * optimisticPatch: {\n * 'profile.bio': ({ mutationParams }) => mutationParams.profile.bio,\n * 'profile.avatar': ({ mutationParams }) => mutationParams.profile.avatar,\n * },\n * })\n * );\n *\n * // Nested fields are updated optimistically\n * updateUserProfileMutation.mutate({\n * userId: '123',\n * profile: { bio: 'New bio', avatar: 'new-avatar.jpg' }\n * });\n * ```\n */\nexport function insertReactOnMutation<\n QueryResourceState extends object | undefined,\n QueryResourceParams,\n QueryResourceArgsParams,\n QueryIsMethod extends boolean,\n QuerySourceParams,\n QueryGroupIdentifier,\n QueryInsertions,\n MutationResourceState,\n MutationResourceParams,\n MutationResourceArgsParams,\n MutationIsMethod,\n MutationSourceParams,\n MutationGroupIdentifier,\n MutationInsertions,\n>(\n mutation:\n | ResourceLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions\n >\n | ResourceByIdLikeMutationRef<\n MutationResourceState,\n MutationResourceParams,\n MutationIsMethod,\n MutationResourceArgsParams,\n MutationSourceParams,\n MutationInsertions,\n MutationGroupIdentifier\n >,\n mutationEffectOptions: QueryDeclarativeEffect<{\n query: InternalType<\n NoInfer<QueryResourceState>,\n NoInfer<QueryResourceParams>,\n NoInfer<QueryResourceArgsParams>,\n [unknown] extends [NoInfer<QueryGroupIdentifier>] ? false : true,\n NoInfer<QueryIsMethod>,\n NoInfer<QueryInsertions>,\n NoInfer<QueryGroupIdentifier>,\n NoInfer<QuerySourceParams>\n >;\n mutation: InternalType<\n NoInfer<MutationResourceState>,\n NoInfer<MutationResourceParams>,\n NoInfer<MutationResourceArgsParams>,\n [unknown] extends [MutationGroupIdentifier] ? false : true,\n NoInfer<MutationIsMethod>,\n NoInfer<MutationInsertions>,\n NoInfer<MutationGroupIdentifier>,\n NoInfer<MutationSourceParams>\n >;\n }>,\n) {\n return (\n context:\n | InsertionParams<\n QueryResourceState,\n QueryResourceParams,\n QueryInsertions\n >\n | {\n // ! avoid to use InsertionByIdParams it is broking the typing inference\n resourceById: ResourceByIdRef<\n QueryGroupIdentifier & string,\n QueryResourceState,\n QueryResourceParams\n >;\n resourceParamsSrc: WritableSignal<QueryResourceParams | undefined>;\n identifier: (\n params: NonNullable<QueryResourceParams>,\n ) => QueryGroupIdentifier;\n insertions: keyof QueryInsertions extends string\n ? QueryInsertions\n : never;\n },\n ) => {\n return reactOnMutationEffect(\n {\n queryTargeted: ('resource' in context\n ? context.resource\n : context.resourceById) as unknown as\n | ResourceLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions\n >\n | ResourceByIdLikeQueryRef<\n QueryResourceState,\n QueryResourceParams,\n QueryIsMethod,\n QueryResourceArgsParams,\n QuerySourceParams,\n QueryInsertions,\n QueryGroupIdentifier\n >,\n mutationTargeted: mutation,\n },\n mutationEffectOptions,\n );\n };\n}\n","import { computed } from '@angular/core';\nimport { InsertionByIdParams } from './query.core';\n\n/**\n * Provides placeholder data during pagination transitions for a smoother user experience.\n *\n * When navigating between pages, this insertion shows the previous page's data while\n * the new page is loading, avoiding empty states during transitions.\n *\n * @returns An object containing:\n * - `currentPageData`: Signal with the current page data or placeholder data during loading\n * - `currentPageStatus`: Signal with the ResourceStatus of the current page\n * - `isPlaceHolderData`: Signal indicating if placeholder data is being shown\n * - `currentIdentifier`: Signal with the current page identifier\n *\n * @example\n * ```typescript\n * const pagination = signal(1);\n *\n * const userQuery = query(\n * {\n * params: pagination,\n * identifier: (params) => '' + params,\n * loader: async ({ params: page }) => fetchUsers(page),\n * },\n * insertPaginationPlaceholderData,\n * );\n *\n * // Access the data (or placeholder during loading)\n * const data = userQuery.currentPageData();\n *\n * // Check if showing placeholder\n * const isPlaceholder = userQuery.isPlaceHolderData();\n * ```\n */\nexport const insertPaginationPlaceholderData = <\n QueryResourceState extends object | undefined,\n QueryResourceParams,\n QueryResourceArgsParams,\n QueryIsMethod extends boolean,\n QuerySourceParams,\n QueryGroupIdentifier extends string,\n QueryInsertions,\n PreviousInsertionsOutputs,\n>({\n resourceById,\n resourceParamsSrc,\n identifier,\n}: InsertionByIdParams<\n QueryGroupIdentifier,\n QueryResourceState,\n QueryResourceParams,\n PreviousInsertionsOutputs\n>) => {\n let previousPageKey: QueryGroupIdentifier | undefined;\n const showPlaceHolderData = computed(() => {\n const page = resourceParamsSrc();\n const resources = resourceById();\n const pageKey = page ? identifier(page) : undefined;\n if (!pageKey) {\n return false;\n }\n const currentResource = resources[pageKey];\n // true if loading and previousPage is used\n if (\n currentResource?.status() === 'loading' &&\n !currentResource?.value() &&\n previousPageKey !== undefined &&\n resources[previousPageKey]\n ) {\n return true;\n }\n return false;\n });\n return {\n currentPageData: computed(() => {\n const page = resourceParamsSrc();\n\n const resources = resourceById();\n const pageKey = page ? identifier(page) : undefined;\n if (!pageKey) {\n return;\n }\n const currentResource = resources[pageKey];\n\n if (showPlaceHolderData()) {\n return resources[previousPageKey]?.hasValue()\n ? resources[previousPageKey]?.value()\n : undefined;\n }\n previousPageKey = pageKey;\n return currentResource?.value();\n }),\n currentPageStatus: computed(() => {\n const page = resourceParamsSrc();\n const resources = resourceById();\n if (!page) {\n return 'idle' as const; // avoid to handle the undefined check\n }\n const pageKey = identifier(page);\n const currentResource = resources[pageKey];\n return currentResource?.status() ?? ('idle' as const);\n }),\n isPlaceHolderData: showPlaceHolderData,\n currentIdentifier: computed(() => {\n const page = resourceParamsSrc();\n if (!page) {\n return '' as QueryGroupIdentifier;\n }\n return identifier(page);\n }),\n };\n};\n","import { Injectable } from '@angular/core';\n\n/**\n * Global service for managing persistence operations.\n *\n * This service provides a centralized way to clear all cached data stored in localStorage\n * by the ng-craft library. It's particularly useful when a user logs out, ensuring all\n * cached queries, mutations, and other persisted data are completely removed.\n *\n * @example\n * ```typescript\n * import { GlobalPersisterHandlerService } from '@craft-ng/core';\n *\n * export class AppComponent {\n * constructor(private persisterHandler: GlobalPersisterHandlerService) {}\n *\n * logout() {\n * // Clear all ng-craft cached data from localStorage\n * this.persisterHandler.clearAllCache();\n * // Proceed with logout logic...\n * }\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class GlobalPersisterHandlerService {\n /**\n * Clears all cached data from localStorage that was created by ng-craft.\n *\n * This method scans all keys in localStorage and removes any key that starts\n * with the 'ng-craft-' prefix. This ensures a complete cleanup of all persisted\n * queries, mutations, and other cached data.\n *\n * **Use cases:**\n * - User logout: Remove all user-specific cached data\n * - Data reset: Clear all cached data to force fresh data loading\n * - Privacy: Ensure no data remains in localStorage after user session\n *\n * @example\n * ```typescript\n * // In a logout handler\n * logout() {\n * this.persisterHandler.clearAllCache();\n * this.router.navigate(['/login']);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Force refresh all data\n * refreshAllData() {\n * this.persisterHandler.clearAllCache();\n * window.location.reload();\n * }\n * ```\n */\n clearAllCache(): void {\n const keysToRemove: string[] = [];\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith('ng-craft-')) {\n keysToRemove.push(key);\n }\n }\n\n keysToRemove.forEach((key) => localStorage.removeItem(key));\n }\n}\n","/**\n * Type to extract the identifier from an entity\n */\nexport type IdSelector<Entity, Key = string | number> = (entity: Entity) => Key;\n\n/**\n * Type for partial updates\n */\nexport type Update<T, K = string | number> = {\n id: K;\n changes: Partial<T>;\n};\n\nexport type EntitiesUtilBrand<Name> = { __brand: Name };\n\n/**\n * Helper function to get the default identifier.\n * For primitives (string | number), the entity itself is used as the identifier.\n * For objects with an `id` property, the `id` property is used.\n */\nfunction getDefaultIdentifier<T, K>(): IdSelector<T, K> {\n return (e: T) => {\n if (typeof e === 'string' || typeof e === 'number') {\n return e as unknown as K;\n }\n return (e as T & { id: K }).id;\n };\n}\n\n/**\n * Removes all elements from the list\n */\nexport function removeAll<T>(): T[] & EntitiesUtilBrand<'removeAll'> {\n return [] as unknown as T[] & EntitiesUtilBrand<'removeAll'>;\n}\n\n/**\n * Adds an element to the end of the list\n */\nexport function addOne<T>({\n entity,\n entities,\n}: {\n entity: T;\n entities: T[];\n}): T[] & EntitiesUtilBrand<'addOne'> {\n return [...entities, entity] as T[] & EntitiesUtilBrand<'addOne'>;\n}\n\n/**\n * Adds multiple elements to the end of the list\n */\nexport function addMany<T>({\n newEntities,\n entities,\n}: {\n newEntities: T[];\n entities: T[];\n}): T[] & EntitiesUtilBrand<'addMany'> {\n return [...entities, ...newEntities] as T[] & EntitiesUtilBrand<'addMany'>;\n}\n\n/**\n * Replaces the entire list with new elements\n */\nexport function setAll<T>({\n newEntities,\n}: {\n newEntities: T[];\n}): T[] & EntitiesUtilBrand<'setAll'> {\n return [...newEntities] as T[] & EntitiesUtilBrand<'setAll'>;\n}\n\n/**\n * Replaces or adds an element (based on id).\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function setOne<T extends string | number>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'setOne'>;\nexport function setOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setOne'>;\nexport function setOne<T, K = string | number>(params: {\n entity: T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setOne'>;\nexport function setOne<T, K = string | number>({\n entity,\n entities,\n identifier,\n}: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const id = getId(entity);\n const index = entities.findIndex((e) => getId(e) === id);\n\n if (index === -1) {\n return [...entities, entity] as T[] & EntitiesUtilBrand<'setOne'>;\n }\n\n return entities.map((e, i) => (i === index ? entity : e)) as T[] &\n EntitiesUtilBrand<'setOne'>;\n}\n\n/**\n * Replaces or adds multiple elements (based on id).\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function setMany<T extends string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'setMany'>;\nexport function setMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setMany'>;\nexport function setMany<T, K = string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setMany'>;\nexport function setMany<T, K = string | number>({\n newEntities,\n entities,\n identifier,\n}: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'setMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const entity of newEntities) {\n result = setOne({ entity, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'setMany'>;\n}\n\n/**\n * Partially updates an existing element.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function updateOne<T extends string | number>(params: {\n update: Update<T, T>;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'updateOne'>;\nexport function updateOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n update: Update<T, K>;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateOne'>;\nexport function updateOne<T, K = string | number>(params: {\n update: Update<T, K>;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateOne'>;\nexport function updateOne<T, K = string | number>({\n update,\n entities,\n identifier,\n}: {\n update: Update<T, K>;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const index = entities.findIndex((e) => getId(e) === update.id);\n\n if (index === -1) {\n return entities as T[] & EntitiesUtilBrand<'updateOne'>;\n }\n\n return entities.map((e, i) =>\n i === index ? { ...e, ...update.changes } : e,\n ) as T[] & EntitiesUtilBrand<'updateOne'>;\n}\n\n/**\n * Partially updates multiple existing elements.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function updateMany<T extends string | number>(params: {\n updates: Update<T, T>[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'updateMany'>;\nexport function updateMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n updates: Update<T, K>[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateMany'>;\nexport function updateMany<T, K = string | number>(params: {\n updates: Update<T, K>[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateMany'>;\nexport function updateMany<T, K = string | number>({\n updates,\n entities,\n identifier,\n}: {\n updates: Update<T, K>[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'updateMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const update of updates) {\n result = updateOne({ update, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'updateMany'>;\n}\n\n/**\n * Updates an element if it exists, otherwise adds it.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function upsertOne<T extends string | number>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'upsertOne'>;\nexport function upsertOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertOne'>;\nexport function upsertOne<T, K = string | number>(params: {\n entity: T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertOne'>;\nexport function upsertOne<T, K = string | number>({\n entity,\n entities,\n identifier,\n}: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const id = getId(entity);\n const index = entities.findIndex((e) => getId(e) === id);\n\n if (index === -1) {\n return [...entities, entity] as T[] & EntitiesUtilBrand<'upsertOne'>;\n }\n\n // For primitives, just replace; for objects, merge\n const isPrimitive = typeof entity === 'string' || typeof entity === 'number';\n return entities.map((e, i) =>\n i === index ? (isPrimitive ? entity : { ...e, ...entity }) : e,\n ) as T[] & EntitiesUtilBrand<'upsertOne'>;\n}\n\n/**\n * Updates multiple elements if they exist, otherwise adds them.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function upsertMany<T extends string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'upsertMany'>;\nexport function upsertMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertMany'>;\nexport function upsertMany<T, K = string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertMany'>;\nexport function upsertMany<T, K = string | number>({\n newEntities,\n entities,\n identifier,\n}: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'upsertMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const entity of newEntities) {\n result = upsertOne({ entity, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'upsertMany'>;\n}\n\n/**\n * Removes an element by its id.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function removeOne<T extends string | number>(params: {\n id: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'removeOne'>;\nexport function removeOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n id: K;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeOne'>;\nexport function removeOne<T, K = string | number>(params: {\n id: K;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeOne'>;\nexport function removeOne<T, K = string | number>({\n id,\n entities,\n identifier,\n}: {\n id: K;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n return entities.filter((e) => getId(e) !== id) as T[] &\n EntitiesUtilBrand<'removeOne'>;\n}\n\n/**\n * Removes multiple elements by their ids.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function removeMany<T extends string | number>(params: {\n ids: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'removeMany'>;\nexport function removeMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n ids: K[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeMany'>;\nexport function removeMany<T, K = string | number>(params: {\n ids: K[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeMany'>;\nexport function removeMany<T, K = string | number>({\n ids,\n entities,\n identifier,\n}: {\n ids: K[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'removeMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const idSet = new Set(ids);\n return entities.filter((e) => !idSet.has(getId(e))) as T[] &\n EntitiesUtilBrand<'removeMany'>;\n}\n\n/**\n * Toggles an element: removes it if it exists, adds it if it doesn't.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function toggleOne<T extends string | number>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'toggleOne'>;\nexport function toggleOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleOne'>;\nexport function toggleOne<T, K = string | number>(params: {\n entity: T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleOne'>;\nexport function toggleOne<T, K = string | number>({\n entity,\n entities,\n identifier,\n}: {\n entity: T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n const id = getId(entity);\n const exists = entities.some((e) => getId(e) === id);\n\n if (exists) {\n return entities.filter((e) => getId(e) !== id) as T[] &\n EntitiesUtilBrand<'toggleOne'>;\n }\n return [...entities, entity] as T[] & EntitiesUtilBrand<'toggleOne'>;\n}\n\n/**\n * Toggles multiple elements: removes them if they exist, adds them if they don't.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function toggleMany<T extends string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'toggleMany'>;\nexport function toggleMany<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleMany'>;\nexport function toggleMany<T, K = string | number>(params: {\n newEntities: T[];\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleMany'>;\nexport function toggleMany<T, K = string | number>({\n newEntities,\n entities,\n identifier,\n}: {\n newEntities: T[];\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'toggleMany'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n let result = [...entities];\n\n for (const entity of newEntities) {\n result = toggleOne({ entity, entities: result, identifier: getId }) as T[];\n }\n\n return result as T[] & EntitiesUtilBrand<'toggleMany'>;\n}\n\n/**\n * Applies a transformation function to all elements\n */\nexport function map<T>({\n mapFn,\n entities,\n}: {\n mapFn: (entity: T) => T;\n entities: T[];\n}): T[] & EntitiesUtilBrand<'map'> {\n return entities.map(mapFn) as T[] & EntitiesUtilBrand<'map'>;\n}\n\n/**\n * Applies a transformation function to a single element by its id.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function mapOne<T extends string | number>(params: {\n id: T;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'mapOne'>;\nexport function mapOne<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n id: K;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'mapOne'>;\nexport function mapOne<T, K = string | number>(params: {\n id: K;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'mapOne'>;\nexport function mapOne<T, K = string | number>({\n id,\n mapFn,\n entities,\n identifier,\n}: {\n id: K;\n mapFn: (entity: T) => T;\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): T[] & EntitiesUtilBrand<'mapOne'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n return entities.map((e) => (getId(e) === id ? mapFn(e) : e)) as T[] &\n EntitiesUtilBrand<'mapOne'>;\n}\n\n/**\n * Returns the total count of entities\n */\nexport function computedTotal<T>({ entities }: { entities: T[] }): number {\n return entities.length;\n}\n\n/**\n * Returns all ids from the entities list.\n * If the entity has an `id` property, the identifier is optional.\n * For primitives (string | number), the entity itself is used as the identifier.\n */\nexport function computedIds<T extends string | number>(params: {\n entities: T[];\n identifier?: IdSelector<T, T>;\n}): T[] & EntitiesUtilBrand<'computedIds'>;\nexport function computedIds<\n T extends { id: K },\n K = T extends { id: infer I } ? I : string | number,\n>(params: {\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): K[] & EntitiesUtilBrand<'computedIds'>;\nexport function computedIds<T, K = string | number>(params: {\n entities: T[];\n identifier: IdSelector<T, K>;\n}): K[] & EntitiesUtilBrand<'computedIds'>;\nexport function computedIds<T, K = string | number>({\n entities,\n identifier,\n}: {\n entities: T[];\n identifier?: IdSelector<T, K>;\n}): K[] & EntitiesUtilBrand<'computedIds'> {\n const getId = identifier ?? getDefaultIdentifier<T, K>();\n return entities.map(getId) as K[] & EntitiesUtilBrand<'computedIds'>;\n}\n","import { linkedSignal, untracked, WritableSignal } from '@angular/core';\n\n/**\n * Options to control when a sync reaction callback is executed.\n */\ntype SyncOptions = {\n /**\n * If `true`, the callback is executed only during initialization\n * and will be ignored on subsequent source changes.\n */\n onInitOnly?: boolean;\n /**\n * If `true`, the callback is executed during initialization\n * AND on subsequent source changes.\n */\n onInitToo?: boolean;\n};\n\n/**\n * Creates a writable signal that reacts to changes in other signals (sources).\n *\n * Built on top of Angular's `linkedSignal`, it compares source references to determine\n * if a reaction callback should be called. When a source's reference changes (`!==`),\n * the associated callback is executed with the new value and the current state.\n *\n * **Important:** During the same reactive cycle, multiple callbacks can be triggered.\n * The order of reactions in the object matters - callbacks are executed in declaration order.\n * Place reactions that should run first at the top.\n *\n * @param initialValue - The initial value of the signal\n * @param reactionBuilder - A function that receives a `sync` helper and returns an object\n * of named reactions. Each reaction defines a source signal and a computation callback.\n *\n * @returns A `WritableSignal` that can be read, set, or updated manually, while also\n * reacting to source changes.\n *\n * @example\n * ```typescript\n * const selectedRows = reactiveWritableSignal([] as string[], (sync) => ({\n * resetOnPageResolved: sync(\n * pageStatus, // Signal<ResourceStatus>\n * ({ params, current }) => (params === 'resolved' ? [] : current),\n * ),\n * removeDeleted: sync(\n * deletedIds, // Signal<string[]>\n * ({ params, current }) => current.filter(id => !params.includes(id)),\n * ),\n * }));\n * ```\n *\n * @see SyncOptions for `onInitOnly` and `onInitToo` options\n */\ntype ReactionEntry<State, Params> = {\n source: () => Params;\n computation: (payload: {\n params: NoInfer<Params>;\n current: NoInfer<State>;\n }) => NoInfer<State>;\n options?: SyncOptions;\n};\n\ntype SourcesSnapshot = Map<string, unknown>;\n\nexport function reactiveWritableSignal<State>(\n initialValue: State,\n reactionBuilder: (\n sync: <Params>(\n source: () => Params,\n computation: (payload: {\n params: NoInfer<Params>;\n current: NoInfer<State>;\n }) => NoInfer<State>,\n options?: SyncOptions,\n ) => ReactionEntry<State, Params>,\n ) => Record<string, ReactionEntry<State, any>>,\n): WritableSignal<State> {\n // Helper function to create reaction entries\n const sync = <Params>(\n source: () => Params,\n computation: (payload: {\n params: NoInfer<Params>;\n current: NoInfer<State>;\n }) => NoInfer<State>,\n options?: SyncOptions,\n ): ReactionEntry<State, Params> => ({\n source,\n computation,\n options,\n });\n\n // Build all reactions\n const reactions = reactionBuilder(sync);\n\n // Create a snapshot of all source values\n const getSourcesSnapshot = (): SourcesSnapshot => {\n const snapshot = new Map<string, unknown>();\n for (const [name, reaction] of Object.entries(reactions)) {\n snapshot.set(name, reaction.source());\n }\n return snapshot;\n };\n\n // Use linkedSignal to track source changes\n const sig = linkedSignal<SourcesSnapshot, State>({\n source: getSourcesSnapshot,\n computation: (currentSnapshot, previous) => {\n const isInitialization = !previous;\n let currentState = isInitialization ? initialValue : previous.value;\n const previousSnapshot = previous?.source;\n\n untracked(() => {\n // Check which sources changed (by reference) and run their computations\n for (const [name, reaction] of Object.entries(reactions)) {\n const currentValue = currentSnapshot.get(name);\n const previousValue = previousSnapshot?.get(name);\n const options = reaction.options;\n\n const hasSourceChanged = currentValue !== previousValue;\n\n // Determine if we should run the computation\n let shouldRun = false;\n\n if (isInitialization) {\n // During initialization: run if onInitOnly or onInitToo\n if (options?.onInitOnly || options?.onInitToo) {\n shouldRun = true;\n }\n } else {\n // After initialization: run if source changed AND not onInitOnly\n if (hasSourceChanged && !options?.onInitOnly) {\n shouldRun = true;\n }\n }\n\n if (shouldRun) {\n currentState = reaction.computation({\n params: currentValue,\n current: currentState,\n });\n }\n }\n });\n\n return currentState;\n },\n });\n\n return sig;\n}\n","import {\n DestroyRef,\n EventEmitter,\n inject,\n Signal,\n signal,\n} from '@angular/core';\n\nexport type SourceSubscribe<T> = {\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n};\n\nexport type Source$<T> = {\n emit: (value: T) => void;\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n asReadonly: () => ReadonlySource$<T>;\n preserveLastValue: () => {\n emit: (value: T) => void;\n subscribe: (callback: (value: T) => void) => void;\n asReadonly: () => {\n subscribe: (callback: (value: T) => void) => void;\n value: Signal<T | undefined>;\n };\n value: Signal<T | undefined>;\n };\n value: Signal<T | undefined>;\n};\n\nexport type ReadonlySource$<T> = {\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n value: Signal<T | undefined>;\n};\n\n/**\n * Creates an event emitter with automatic cleanup and signal-based value tracking.\n *\n * `source$` provides a lightweight event streaming solution that combines event emission,\n * automatic subscription cleanup via `DestroyRef`, and signal-based reactive value tracking.\n *\n * @template T - The type of values emitted by the source\n *\n * @returns {Source$<T>} An object with the following methods and properties:\n * - `emit(value: T)` - Emits a value to all subscribers and updates the internal signal\n * - `subscribe(callback: (value: T) => void)` - Subscribes to emissions with automatic cleanup\n * - `value: Signal<T | undefined>` - A read-only signal containing the last emitted value\n * - `asReadonly()` - Returns a read-only version (only `subscribe` and `value`)\n * - `preserveLastValue()` - Returns a variant that immediately emits the last value to new subscribers\n *\n * @example\n * Basic usage with state coordination\n * ```typescript\n * import { source$, state, on$ } from '@craft-ng/core';\n *\n * @Component({\n * selector: 'app-counter',\n * template: `\n * <p>Count: {{ counter() }}</p>\n * <button (click)=\"counter.increment()\">+1</button>\n * <button (click)=\"reset$.emit()\">Reset</button>\n * `,\n * })\n * export class CounterComponent {\n * reset$ = source$<void>();\n *\n * counter = state(0, ({ set, update }) => ({\n * increment: () => update((v) => v + 1),\n * reset: on$(this.reset$, () => set(0)),\n * }));\n * }\n * ```\n *\n *\n * @example\n * Late subscriber with preserved last value\n * ```typescript\n * const notifications$ = source$<string>().preserveLastValue();\n *\n * notifications$.emit('Server started');\n * notifications$.emit('Database connected');\n *\n * // Late subscriber receives the last value immediately\n * notifications$.subscribe((msg) => {\n * console.log(msg); // 'Database connected'\n * });\n * ```\n *\n * @example\n * Read-only access pattern\n * ```typescript\n * class DataService {\n * private dataUpdated$ = source$<Data>();\n * readonly dataUpdated = this.dataUpdated$.asReadonly();\n *\n * updateData(data: Data) {\n * this.dataUpdated$.emit(data);\n * }\n * }\n * ```\n *\n * @see {@link https://ng-craft.dev/utils/source$ | source$ documentation}\n */\nexport function source$<T>(): Source$<T> {\n const sourceRef$ = new EventEmitter<T>();\n const destroyRef = inject(DestroyRef);\n\n const sourceAsSignal = signal<T | undefined>(undefined);\n\n return {\n emit: (value: T) => {\n sourceRef$.emit(value);\n sourceAsSignal.set(value);\n },\n subscribe: (callback: (value: T) => void) => sourceRef$.subscribe(callback),\n preserveLastValue: () => {\n const sourceWithLastValueRef = new EventEmitter<T>();\n const subscriptionWithLastLastValue = sourceRef$.subscribe((value) => {\n sourceWithLastValueRef.emit(value);\n });\n\n destroyRef.onDestroy(() => subscriptionWithLastLastValue.unsubscribe());\n\n return {\n emit: (value: T) => {\n sourceWithLastValueRef.emit(value);\n sourceAsSignal.set(value);\n },\n subscribe: (callback: (value: T) => void) => {\n sourceWithLastValueRef.subscribe(callback);\n sourceWithLastValueRef.emit(sourceAsSignal());\n },\n asReadonly: () => ({\n subscribe: (callback: (value: T) => void) => {\n sourceWithLastValueRef.subscribe(callback);\n sourceWithLastValueRef.emit(sourceAsSignal());\n },\n value: sourceAsSignal.asReadonly(),\n }),\n value: sourceAsSignal.asReadonly(),\n };\n },\n value: sourceAsSignal.asReadonly(),\n asReadonly: () => ({\n subscribe: (callback: (value: T) => void) =>\n sourceRef$.subscribe(callback),\n value: sourceAsSignal.asReadonly(),\n }),\n };\n}\n","import { assertInInjectionContext, DestroyRef, inject } from '@angular/core';\nimport { source$ } from './source$';\nimport type { ReadonlySource$ } from './source$';\n\nexport type FromEventToSource$<T> = ReadonlySource$<T> & {\n dispose: () => void;\n};\n\n/**\n * Converts DOM events to a ReadonlySource$ stream with automatic cleanup on component destruction.\n *\n * This function bridges DOM events with ng-craft's source$ reactive system by:\n * - Converting native DOM events to source emissions\n * - Automatically removing event listeners on component destruction\n * - Supporting optional event payload transformation\n * - Providing manual disposal capability\n * - Returning a readonly source with `subscribe` and `value` properties\n *\n * @remarks\n * **Automatic Cleanup:**\n * - Event listeners are automatically removed when the injection context is destroyed\n * - Uses Angular's `DestroyRef` for lifecycle management\n * - Manual cleanup available via `dispose()` method\n * - Prevents memory leaks from dangling event listeners\n *\n * **Use Cases:**\n * - **User interactions**: Click, input, scroll, keyboard events\n * - **Window events**: Resize, scroll, focus, online/offline\n * - **Document events**: Visibility changes, custom events\n * - **Media events**: Video/audio play, pause, ended\n * - **Form events**: Submit, change, input\n * - **Custom events**: Application-specific DOM events\n *\n * **Event Transformation:**\n * - Without `computedValue`: Emits the raw event object\n * - With `computedValue`: Transforms event before emission\n * - Useful for extracting specific event properties\n * - Reduces payload size and improves type safety\n *\n * **Integration with Stores:**\n * - Use the readonly source in queries/mutations via `on$()`\n * - Trigger async operations on DOM events\n * - Coordinate multiple components via event sources\n *\n * **Injection Context:**\n * - Must be called within Angular injection context\n * - Typically called in component constructor or class fields\n * - Uses `assertInInjectionContext()` for safety\n *\n * @template T - The type of the event object\n * @template ComputedValue - The type after optional transformation\n *\n * @param target - The DOM element or event target to listen to.\n * Can be any EventTarget (HTMLElement, Window, Document, etc.)\n *\n * @param eventName - The name of the event to listen for.\n * Standard DOM event names: 'click', 'input', 'scroll', etc.\n *\n * @param options - Optional configuration:\n * - `event`: Event listener options (capture, passive, once, etc.)\n * - `computedValue`: Function to transform event before emission\n *\n * @returns A readonly source that emits on DOM events with:\n * - `subscribe()`: Subscribe to event emissions\n * - `value`: Signal containing the last emitted value\n * - `dispose()`: Method to manually remove event listener\n * - Automatic cleanup on component destruction\n *\n * @example\n * Basic click event source\n * ```ts\n * @Component({\n * selector: 'app-clicker',\n * template: '<button #btn>Click me</button>',\n * })\n * export class ClickerComponent {\n * @ViewChild('btn', { read: ElementRef }) button!: ElementRef<HTMLButtonElement>;\n *\n * click$ = fromEventToSource$<MouseEvent>(\n * this.button.nativeElement,\n * 'click'\n * );\n *\n * counter = state(0, ({ update }) => ({\n * increment: on$(this.click$, () => update((v) => v + 1)),\n * }));\n * }\n * ```\n *\n * @example\n * Window scroll event with transformation\n * ```ts\n * @Component({\n * selector: 'app-infinite-scroll',\n * template: '...',\n * })\n * export class InfiniteScrollComponent {\n * scroll$ = fromEventToSource$(window, 'scroll', {\n * computedValue: () => ({\n * scrollY: window.scrollY,\n * scrollHeight: document.documentElement.scrollHeight,\n * clientHeight: window.innerHeight,\n * }),\n * event: { passive: true },\n * });\n *\n * // Access scroll position via signal\n * scrollPosition = this.scroll$.value;\n *\n * // Subscribe to scroll events\n * ngOnInit() {\n * this.scroll$.subscribe((data) => {\n * const nearBottom = data.scrollY + data.clientHeight >= data.scrollHeight - 100;\n * if (nearBottom) {\n * // Load more data\n * }\n * });\n * }\n * }\n * ```\n *\n * @example\n * Form input event for real-time search\n * ```ts\n * @Component({\n * selector: 'app-search',\n * template: '<input #searchInput type=\"text\" placeholder=\"Search...\" />',\n * })\n * export class SearchComponent {\n * @ViewChild('searchInput', { read: ElementRef }) input!: ElementRef<HTMLInputElement>;\n *\n * input$ = fromEventToSource$(this.input.nativeElement, 'input', {\n * computedValue: (event: Event) => {\n * const target = event.target as HTMLInputElement;\n * return target.value;\n * },\n * });\n *\n * // Current input value as signal\n * searchTerm = this.input$.value;\n *\n * // React to input changes\n * searchResults = state([], ({ set }) => ({\n * search: on$(this.input$, async (term) => {\n * if (term.length < 3) {\n * set([]);\n * return;\n * }\n * const results = await fetchResults(term);\n * set(results);\n * }),\n * }));\n * }\n * ```\n *\n * @example\n * Window resize event\n * ```ts\n * @Component({\n * selector: 'app-responsive',\n * template: '...',\n * })\n * export class ResponsiveComponent {\n * resize$ = fromEventToSource$(window, 'resize', {\n * computedValue: () => ({\n * width: window.innerWidth,\n * height: window.innerHeight,\n * }),\n * });\n *\n * dimensions = this.resize$.value;\n * }\n * ```\n *\n * @example\n * Manual disposal for dynamic elements\n * ```ts\n * @Component({\n * selector: 'app-dynamic',\n * template: '...',\n * })\n * export class DynamicComponent {\n * private click$?: FromEventToSource$<MouseEvent>;\n *\n * attachListener(element: HTMLElement) {\n * // Remove previous listener if exists\n * this.click$?.dispose();\n *\n * // Attach to new element\n * this.click$ = fromEventToSource$<MouseEvent>(element, 'click');\n * }\n *\n * detachListener() {\n * // Manually remove listener before component destruction\n * this.click$?.dispose();\n * this.click$ = undefined;\n * }\n * }\n * ```\n *\n * @see {@link https://ng-craft.dev/utils/from-event-to-source$ | fromEventToSource$ documentation}\n */\nexport function fromEventToSource$<T>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: never;\n },\n): FromEventToSource$<T>;\nexport function fromEventToSource$<T, ComputedValue>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue: (event: T) => ComputedValue;\n },\n): FromEventToSource$<ComputedValue>;\nexport function fromEventToSource$(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: (event: Event) => unknown;\n },\n): FromEventToSource$<unknown> {\n assertInInjectionContext(fromEventToSource$);\n\n const eventSource$ = source$<unknown>();\n\n const listener = (event: Event) => {\n if (options?.computedValue) {\n const computed = options.computedValue(event);\n eventSource$.emit(computed);\n return;\n }\n eventSource$.emit(event);\n };\n\n target.addEventListener(eventName, listener, options?.event);\n\n const destroyRef = inject(DestroyRef);\n\n const dispose = () => {\n target.removeEventListener(eventName, listener, options?.event);\n };\n\n destroyRef.onDestroy(() => {\n dispose();\n });\n\n return Object.assign(eventSource$.asReadonly(), {\n dispose,\n });\n}\n","import { DestroyRef, EventEmitter, inject } from '@angular/core';\nimport { SourceBranded } from './util/util';\n\nexport function on$<State, SourceType>(\n _source: {\n subscribe: EventEmitter<SourceType>['subscribe'];\n },\n callback: (source: SourceType) => State,\n): SourceBranded {\n const sub = _source.subscribe((value) => {\n callback(value);\n });\n\n const destroyRef = inject(DestroyRef);\n destroyRef.onDestroy(() => sub.unsubscribe());\n\n return SourceBranded;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}