@tstdl/base 0.93.182 → 0.93.183
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/server/api-request-token.provider.js +1 -1
- package/api/server/gateway.js +6 -1
- package/authentication/authentication.api.d.ts +13 -40
- package/authentication/authentication.api.js +5 -14
- package/authentication/client/authentication.service.d.ts +6 -14
- package/authentication/client/authentication.service.js +22 -4
- package/authentication/client/module.d.ts +1 -1
- package/authentication/client/module.js +4 -4
- package/authentication/models/index.d.ts +1 -0
- package/authentication/models/index.js +1 -0
- package/authentication/models/totp-results.model.d.ts +11 -0
- package/authentication/models/totp-results.model.js +37 -0
- package/authentication/server/authentication.api-controller.d.ts +3 -3
- package/authentication/server/authentication.api-controller.js +31 -4
- package/authentication/server/authentication.service.d.ts +5 -14
- package/authentication/server/authentication.service.js +6 -4
- package/core.d.ts +0 -5
- package/core.js +0 -8
- package/document-management/api/document-management.api.d.ts +2 -2
- package/document-management/service-models/document.service-model.d.ts +1 -1
- package/examples/config.d.ts +25 -0
- package/examples/config.js +26 -0
- package/notification/server/module.d.ts +1 -1
- package/notification/server/module.js +1 -1
- package/package.json +5 -5
- package/signals/api.d.ts +5 -1
- package/signals/api.js +3 -1
- package/signals/implementation/api.d.ts +13 -5
- package/signals/implementation/api.js +7 -1
- package/signals/implementation/asserts.d.ts +2 -2
- package/signals/implementation/asserts.js +3 -3
- package/signals/implementation/computed.d.ts +7 -34
- package/signals/implementation/computed.js +14 -83
- package/signals/implementation/configure.js +6 -2
- package/signals/implementation/effect.d.ts +65 -46
- package/signals/implementation/effect.js +97 -62
- package/signals/implementation/index.d.ts +2 -4
- package/signals/implementation/index.js +2 -4
- package/signals/implementation/linked_signal.d.ts +36 -0
- package/signals/implementation/linked_signal.js +34 -0
- package/signals/implementation/primitive/computed.d.ts +55 -0
- package/signals/implementation/primitive/computed.js +107 -0
- package/signals/implementation/primitive/effect.d.ts +26 -0
- package/signals/implementation/primitive/effect.js +31 -0
- package/signals/implementation/{equality.d.ts → primitive/equality.d.ts} +1 -1
- package/signals/implementation/{equality.js → primitive/equality.js} +1 -1
- package/signals/implementation/primitive/errors.d.ts +10 -0
- package/signals/implementation/{errors.js → primitive/errors.js} +3 -4
- package/signals/implementation/primitive/formatter.d.ts +19 -0
- package/signals/implementation/primitive/formatter.js +136 -0
- package/signals/implementation/{graph.d.ts → primitive/graph.d.ts} +68 -36
- package/signals/implementation/primitive/graph.js +386 -0
- package/signals/implementation/primitive/linked_signal.d.ts +46 -0
- package/signals/implementation/primitive/linked_signal.js +110 -0
- package/signals/implementation/primitive/signal.d.ts +31 -0
- package/signals/implementation/primitive/signal.js +80 -0
- package/signals/implementation/primitive/untracked.d.ts +12 -0
- package/signals/implementation/primitive/untracked.js +23 -0
- package/signals/implementation/{watch.d.ts → primitive/watch.d.ts} +1 -2
- package/signals/implementation/{watch.js → primitive/watch.js} +22 -16
- package/signals/implementation/resource/api.d.ts +275 -0
- package/signals/implementation/resource/api.js +26 -0
- package/signals/implementation/resource/debounce.d.ts +13 -0
- package/signals/implementation/resource/debounce.js +113 -0
- package/signals/implementation/resource/from_snapshots.d.ts +16 -0
- package/signals/implementation/resource/from_snapshots.js +44 -0
- package/signals/implementation/resource/index.d.ts +11 -0
- package/signals/implementation/resource/index.js +11 -0
- package/signals/implementation/resource/resource.d.ts +110 -0
- package/signals/implementation/resource/resource.js +402 -0
- package/signals/implementation/root_effect_scheduler.d.ts +50 -0
- package/signals/implementation/root_effect_scheduler.js +66 -0
- package/signals/implementation/signal.d.ts +42 -18
- package/signals/implementation/signal.js +29 -49
- package/signals/implementation/to-observable.d.ts +12 -5
- package/signals/implementation/to-observable.js +12 -2
- package/signals/implementation/to-signal.d.ts +9 -18
- package/signals/implementation/to-signal.js +46 -13
- package/signals/implementation/untracked.d.ts +1 -1
- package/signals/implementation/untracked.js +3 -11
- package/signals/operators/debounce.d.ts +8 -0
- package/signals/operators/debounce.js +19 -0
- package/signals/operators/derive-async.js +43 -15
- package/signals/operators/index.d.ts +2 -0
- package/signals/operators/index.js +2 -0
- package/signals/operators/throttle.d.ts +8 -0
- package/signals/operators/throttle.js +31 -0
- package/ai/genkit/tests/multi-region.test.d.ts +0 -2
- package/ai/genkit/tests/multi-region.test.js +0 -179
- package/ai/genkit/tests/token-limit-fallback.test.d.ts +0 -2
- package/ai/genkit/tests/token-limit-fallback.test.js +0 -209
- package/ai/prompts/tests/prompt-builder.test.d.ts +0 -1
- package/ai/prompts/tests/prompt-builder.test.js +0 -22
- package/ai/tests/instructions-formatter.test.d.ts +0 -1
- package/ai/tests/instructions-formatter.test.js +0 -116
- package/ai/tests/steering.test.d.ts +0 -1
- package/ai/tests/steering.test.js +0 -37
- package/api/client/tests/api-client.test.d.ts +0 -1
- package/api/client/tests/api-client.test.js +0 -194
- package/api/server/tests/csrf.middleware.test.d.ts +0 -1
- package/api/server/tests/csrf.middleware.test.js +0 -91
- package/authentication/tests/authentication-password-requirements.validator.test.d.ts +0 -1
- package/authentication/tests/authentication-password-requirements.validator.test.js +0 -29
- package/authentication/tests/authentication.api-controller.test.d.ts +0 -1
- package/authentication/tests/authentication.api-controller.test.js +0 -156
- package/authentication/tests/authentication.api-request-token.provider.test.d.ts +0 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +0 -48
- package/authentication/tests/authentication.client-error-handling.test.d.ts +0 -1
- package/authentication/tests/authentication.client-error-handling.test.js +0 -123
- package/authentication/tests/authentication.client-middleware.test.d.ts +0 -1
- package/authentication/tests/authentication.client-middleware.test.js +0 -118
- package/authentication/tests/authentication.client-service-methods.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-methods.test.js +0 -177
- package/authentication/tests/authentication.client-service-refresh.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-refresh.test.js +0 -153
- package/authentication/tests/authentication.client-service.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service.test.js +0 -76
- package/authentication/tests/authentication.refresh-busy-loop.test.d.ts +0 -1
- package/authentication/tests/authentication.refresh-busy-loop.test.js +0 -84
- package/authentication/tests/authentication.service.test.d.ts +0 -1
- package/authentication/tests/authentication.service.test.js +0 -167
- package/authentication/tests/authentication.test-ancillary-service.d.ts +0 -9
- package/authentication/tests/authentication.test-ancillary-service.js +0 -27
- package/authentication/tests/brute-force-protection.test.d.ts +0 -1
- package/authentication/tests/brute-force-protection.test.js +0 -211
- package/authentication/tests/helper.test.d.ts +0 -1
- package/authentication/tests/helper.test.js +0 -122
- package/authentication/tests/password-requirements.error.test.d.ts +0 -1
- package/authentication/tests/password-requirements.error.test.js +0 -14
- package/authentication/tests/remember.api.test.d.ts +0 -1
- package/authentication/tests/remember.api.test.js +0 -117
- package/authentication/tests/remember.service.test.d.ts +0 -1
- package/authentication/tests/remember.service.test.js +0 -83
- package/authentication/tests/subject.service.test.d.ts +0 -1
- package/authentication/tests/subject.service.test.js +0 -140
- package/authentication/tests/suspended-subject.test.d.ts +0 -1
- package/authentication/tests/suspended-subject.test.js +0 -120
- package/authentication/tests/totp.enrollment.test.d.ts +0 -1
- package/authentication/tests/totp.enrollment.test.js +0 -123
- package/authentication/tests/totp.login.test.d.ts +0 -1
- package/authentication/tests/totp.login.test.js +0 -213
- package/authentication/tests/totp.recovery-codes.test.d.ts +0 -1
- package/authentication/tests/totp.recovery-codes.test.js +0 -97
- package/authentication/tests/totp.status.test.d.ts +0 -1
- package/authentication/tests/totp.status.test.js +0 -72
- package/cancellation/tests/coverage.test.d.ts +0 -1
- package/cancellation/tests/coverage.test.js +0 -49
- package/cancellation/tests/leak.test.d.ts +0 -1
- package/cancellation/tests/leak.test.js +0 -35
- package/cancellation/tests/token.test.d.ts +0 -1
- package/cancellation/tests/token.test.js +0 -136
- package/circuit-breaker/tests/circuit-breaker.test.d.ts +0 -1
- package/circuit-breaker/tests/circuit-breaker.test.js +0 -116
- package/cryptography/tests/cryptography.test.d.ts +0 -1
- package/cryptography/tests/cryptography.test.js +0 -175
- package/cryptography/tests/jwt.test.d.ts +0 -1
- package/cryptography/tests/jwt.test.js +0 -54
- package/cryptography/tests/modern.test.d.ts +0 -1
- package/cryptography/tests/modern.test.js +0 -105
- package/cryptography/tests/module.test.d.ts +0 -1
- package/cryptography/tests/module.test.js +0 -100
- package/cryptography/tests/totp.test.d.ts +0 -1
- package/cryptography/tests/totp.test.js +0 -108
- package/document-management/tests/ai-config-hierarchy.test.d.ts +0 -1
- package/document-management/tests/ai-config-hierarchy.test.js +0 -59
- package/document-management/tests/ai-config-integration.test.d.ts +0 -1
- package/document-management/tests/ai-config-integration.test.js +0 -125
- package/document-management/tests/ai-config-merge.test.d.ts +0 -1
- package/document-management/tests/ai-config-merge.test.js +0 -46
- package/document-management/tests/document-management-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-management-ai-overrides.test.js +0 -63
- package/document-management/tests/document-management-core.test.d.ts +0 -1
- package/document-management/tests/document-management-core.test.js +0 -157
- package/document-management/tests/document-management.api.test.d.ts +0 -1
- package/document-management/tests/document-management.api.test.js +0 -101
- package/document-management/tests/document-statistics.service.test.d.ts +0 -1
- package/document-management/tests/document-statistics.service.test.js +0 -498
- package/document-management/tests/document-validation-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-validation-ai-overrides.test.js +0 -87
- package/document-management/tests/document.service.test.d.ts +0 -1
- package/document-management/tests/document.service.test.js +0 -143
- package/document-management/tests/enum-helpers.test.d.ts +0 -1
- package/document-management/tests/enum-helpers.test.js +0 -452
- package/document-management/tests/helper.d.ts +0 -24
- package/document-management/tests/helper.js +0 -39
- package/errors/tests/format.test.d.ts +0 -1
- package/errors/tests/format.test.js +0 -84
- package/http/tests/server-timing.test.d.ts +0 -1
- package/http/tests/server-timing.test.js +0 -42
- package/injector/tests/advanced.test.d.ts +0 -1
- package/injector/tests/advanced.test.js +0 -116
- package/injector/tests/async-init.test.d.ts +0 -1
- package/injector/tests/async-init.test.js +0 -77
- package/injector/tests/basic.test.d.ts +0 -1
- package/injector/tests/basic.test.js +0 -114
- package/injector/tests/hierarchical.test.d.ts +0 -1
- package/injector/tests/hierarchical.test.js +0 -59
- package/injector/tests/leak.test.d.ts +0 -1
- package/injector/tests/leak.test.js +0 -45
- package/injector/tests/lifecycles.test.d.ts +0 -1
- package/injector/tests/lifecycles.test.js +0 -109
- package/logger/tests/pretty-print.test.d.ts +0 -1
- package/logger/tests/pretty-print.test.js +0 -60
- package/notification/tests/notification-api.test.d.ts +0 -1
- package/notification/tests/notification-api.test.js +0 -124
- package/notification/tests/notification-client.test.d.ts +0 -1
- package/notification/tests/notification-client.test.js +0 -101
- package/notification/tests/notification-flow.test.d.ts +0 -1
- package/notification/tests/notification-flow.test.js +0 -296
- package/notification/tests/notification-sse.service.test.d.ts +0 -1
- package/notification/tests/notification-sse.service.test.js +0 -43
- package/notification/tests/notification-type.service.test.d.ts +0 -1
- package/notification/tests/notification-type.service.test.js +0 -41
- package/object-storage/s3/tests/s3.object-storage.integration.test.d.ts +0 -1
- package/object-storage/s3/tests/s3.object-storage.integration.test.js +0 -303
- package/orm/tests/build-jsonb.test.d.ts +0 -1
- package/orm/tests/build-jsonb.test.js +0 -39
- package/orm/tests/data-types.test.d.ts +0 -1
- package/orm/tests/data-types.test.js +0 -39
- package/orm/tests/database-extension.test.d.ts +0 -1
- package/orm/tests/database-extension.test.js +0 -63
- package/orm/tests/database-migration.test.d.ts +0 -1
- package/orm/tests/database-migration.test.js +0 -83
- package/orm/tests/decorators.test.d.ts +0 -1
- package/orm/tests/decorators.test.js +0 -77
- package/orm/tests/encryption.test.d.ts +0 -1
- package/orm/tests/encryption.test.js +0 -31
- package/orm/tests/query-complex.test.d.ts +0 -1
- package/orm/tests/query-complex.test.js +0 -172
- package/orm/tests/query-converter-complex.test.d.ts +0 -1
- package/orm/tests/query-converter-complex.test.js +0 -131
- package/orm/tests/query-converter.test.d.ts +0 -1
- package/orm/tests/query-converter.test.js +0 -123
- package/orm/tests/repository-advanced.test.d.ts +0 -1
- package/orm/tests/repository-advanced.test.js +0 -189
- package/orm/tests/repository-attributes.test.d.ts +0 -1
- package/orm/tests/repository-attributes.test.js +0 -83
- package/orm/tests/repository-compound-primary-key.test.d.ts +0 -2
- package/orm/tests/repository-compound-primary-key.test.js +0 -226
- package/orm/tests/repository-comprehensive.test.d.ts +0 -1
- package/orm/tests/repository-comprehensive.test.js +0 -162
- package/orm/tests/repository-coverage.test.d.ts +0 -2
- package/orm/tests/repository-coverage.test.js +0 -242
- package/orm/tests/repository-cti-complex.test.d.ts +0 -1
- package/orm/tests/repository-cti-complex.test.js +0 -151
- package/orm/tests/repository-cti-embedded.test.d.ts +0 -1
- package/orm/tests/repository-cti-embedded.test.js +0 -178
- package/orm/tests/repository-cti-extensive.test.d.ts +0 -2
- package/orm/tests/repository-cti-extensive.test.js +0 -279
- package/orm/tests/repository-cti-mapping.test.d.ts +0 -2
- package/orm/tests/repository-cti-mapping.test.js +0 -108
- package/orm/tests/repository-cti-search.test.d.ts +0 -1
- package/orm/tests/repository-cti-search.test.js +0 -141
- package/orm/tests/repository-cti-soft-delete.test.d.ts +0 -2
- package/orm/tests/repository-cti-soft-delete.test.js +0 -103
- package/orm/tests/repository-cti-transactions.test.d.ts +0 -1
- package/orm/tests/repository-cti-transactions.test.js +0 -112
- package/orm/tests/repository-cti-upsert-many.test.d.ts +0 -2
- package/orm/tests/repository-cti-upsert-many.test.js +0 -115
- package/orm/tests/repository-cti.test.d.ts +0 -2
- package/orm/tests/repository-cti.test.js +0 -390
- package/orm/tests/repository-edge-cases.test.d.ts +0 -1
- package/orm/tests/repository-edge-cases.test.js +0 -178
- package/orm/tests/repository-expiration.test.d.ts +0 -2
- package/orm/tests/repository-expiration.test.js +0 -140
- package/orm/tests/repository-extra-coverage.test.d.ts +0 -2
- package/orm/tests/repository-extra-coverage.test.js +0 -402
- package/orm/tests/repository-mapping.test.d.ts +0 -2
- package/orm/tests/repository-mapping.test.js +0 -65
- package/orm/tests/repository-regression.test.d.ts +0 -1
- package/orm/tests/repository-regression.test.js +0 -288
- package/orm/tests/repository-search-coverage.test.d.ts +0 -1
- package/orm/tests/repository-search-coverage.test.js +0 -107
- package/orm/tests/repository-search.test.d.ts +0 -1
- package/orm/tests/repository-search.test.js +0 -105
- package/orm/tests/repository-soft-delete.test.d.ts +0 -1
- package/orm/tests/repository-soft-delete.test.js +0 -118
- package/orm/tests/repository-transactions-nested.test.d.ts +0 -1
- package/orm/tests/repository-transactions-nested.test.js +0 -178
- package/orm/tests/repository-types.test.d.ts +0 -1
- package/orm/tests/repository-types.test.js +0 -184
- package/orm/tests/repository-undelete.test.d.ts +0 -2
- package/orm/tests/repository-undelete.test.js +0 -201
- package/orm/tests/schema-converter.test.d.ts +0 -1
- package/orm/tests/schema-converter.test.js +0 -82
- package/orm/tests/schema-generation.test.d.ts +0 -2
- package/orm/tests/schema-generation.test.js +0 -174
- package/orm/tests/sql-helpers.test.d.ts +0 -1
- package/orm/tests/sql-helpers.test.js +0 -67
- package/orm/tests/transaction-safety.test.d.ts +0 -1
- package/orm/tests/transaction-safety.test.js +0 -81
- package/orm/tests/transactional.test.d.ts +0 -1
- package/orm/tests/transactional.test.js +0 -215
- package/orm/tests/utils.test.d.ts +0 -1
- package/orm/tests/utils.test.js +0 -70
- package/pdf/tests/utils.test.d.ts +0 -1
- package/pdf/tests/utils.test.js +0 -187
- package/process/tests/spawn.test.d.ts +0 -1
- package/process/tests/spawn.test.js +0 -182
- package/rate-limit/tests/postgres-rate-limiter.test.d.ts +0 -1
- package/rate-limit/tests/postgres-rate-limiter.test.js +0 -84
- package/renderer/tests/renderer.test.d.ts +0 -1
- package/renderer/tests/renderer.test.js +0 -88
- package/rpc/tests/rpc.integration.test.d.ts +0 -1
- package/rpc/tests/rpc.integration.test.js +0 -615
- package/signals/implementation/errors.d.ts +0 -2
- package/signals/implementation/graph.js +0 -312
- package/signals/implementation/writable-signal.d.ts +0 -48
- package/signals/implementation/writable-signal.js +0 -32
- package/task-queue/tests/coverage-branch.test.d.ts +0 -1
- package/task-queue/tests/coverage-branch.test.js +0 -395
- package/task-queue/tests/coverage-enhancement.test.d.ts +0 -1
- package/task-queue/tests/coverage-enhancement.test.js +0 -150
- package/task-queue/tests/dag.test.d.ts +0 -1
- package/task-queue/tests/dag.test.js +0 -188
- package/task-queue/tests/dependencies.test.d.ts +0 -1
- package/task-queue/tests/dependencies.test.js +0 -296
- package/task-queue/tests/enqueue-batch.test.d.ts +0 -1
- package/task-queue/tests/enqueue-batch.test.js +0 -125
- package/task-queue/tests/enqueue-item.test.d.ts +0 -1
- package/task-queue/tests/enqueue-item.test.js +0 -12
- package/task-queue/tests/fan-out-spawning.test.d.ts +0 -1
- package/task-queue/tests/fan-out-spawning.test.js +0 -94
- package/task-queue/tests/idempotent-replacement.test.d.ts +0 -1
- package/task-queue/tests/idempotent-replacement.test.js +0 -114
- package/task-queue/tests/missing-idempotent-tasks.test.d.ts +0 -1
- package/task-queue/tests/missing-idempotent-tasks.test.js +0 -39
- package/task-queue/tests/optimization-edge-cases.test.d.ts +0 -1
- package/task-queue/tests/optimization-edge-cases.test.js +0 -124
- package/task-queue/tests/queue-generic.test.d.ts +0 -1
- package/task-queue/tests/queue-generic.test.js +0 -8
- package/task-queue/tests/queue.test.d.ts +0 -1
- package/task-queue/tests/queue.test.js +0 -756
- package/task-queue/tests/shutdown.test.d.ts +0 -1
- package/task-queue/tests/shutdown.test.js +0 -41
- package/task-queue/tests/task-context.test.d.ts +0 -1
- package/task-queue/tests/task-context.test.js +0 -7
- package/task-queue/tests/task-union.test.d.ts +0 -1
- package/task-queue/tests/task-union.test.js +0 -18
- package/task-queue/tests/transactions.test.d.ts +0 -1
- package/task-queue/tests/transactions.test.js +0 -47
- package/task-queue/tests/typing.test.d.ts +0 -1
- package/task-queue/tests/typing.test.js +0 -9
- package/task-queue/tests/worker.test.d.ts +0 -1
- package/task-queue/tests/worker.test.js +0 -258
- package/task-queue/tests/zombie-parent.test.d.ts +0 -1
- package/task-queue/tests/zombie-parent.test.js +0 -45
- package/task-queue/tests/zombie-recovery.test.d.ts +0 -1
- package/task-queue/tests/zombie-recovery.test.js +0 -51
- package/utils/tests/backoff.test.d.ts +0 -1
- package/utils/tests/backoff.test.js +0 -41
- package/utils/tests/retry-with-backoff.test.d.ts +0 -1
- package/utils/tests/retry-with-backoff.test.js +0 -49
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { type ValueEqualityFn } from './equality.js';
|
|
9
|
+
import { type ReactiveNode, SIGNAL } from './graph.js';
|
|
10
|
+
export type ComputationFn<S, D> = (source: S, previous?: PreviousValue<S, D>) => D;
|
|
11
|
+
export type PreviousValue<S, D> = {
|
|
12
|
+
source: S;
|
|
13
|
+
value: D;
|
|
14
|
+
};
|
|
15
|
+
export interface LinkedSignalNode<S, D> extends ReactiveNode {
|
|
16
|
+
/**
|
|
17
|
+
* Value of the source signal that was used to derive the computed value.
|
|
18
|
+
*/
|
|
19
|
+
sourceValue: S;
|
|
20
|
+
/**
|
|
21
|
+
* Current state value, or one of the sentinel values (`UNSET`, `COMPUTING`,
|
|
22
|
+
* `ERROR`).
|
|
23
|
+
*/
|
|
24
|
+
value: D;
|
|
25
|
+
/**
|
|
26
|
+
* If `value` is `ERRORED`, the error caught from the last computation attempt which will
|
|
27
|
+
* be re-thrown.
|
|
28
|
+
*/
|
|
29
|
+
error: unknown;
|
|
30
|
+
/**
|
|
31
|
+
* The source function represents reactive dependency based on which the linked state is reset.
|
|
32
|
+
*/
|
|
33
|
+
source: () => S;
|
|
34
|
+
/**
|
|
35
|
+
* The computation function which will produce a new value based on the source and, optionally - previous values.
|
|
36
|
+
*/
|
|
37
|
+
computation: ComputationFn<S, D>;
|
|
38
|
+
equal: ValueEqualityFn<D>;
|
|
39
|
+
}
|
|
40
|
+
export type LinkedSignalGetter<S, D> = (() => D) & {
|
|
41
|
+
[SIGNAL]: LinkedSignalNode<S, D>;
|
|
42
|
+
};
|
|
43
|
+
export declare function createLinkedSignal<S, D>(sourceFn: () => S, computationFn: ComputationFn<S, D>, equalityFn?: ValueEqualityFn<D>): LinkedSignalGetter<S, D>;
|
|
44
|
+
export declare function linkedSignalSetFn<S, D>(node: LinkedSignalNode<S, D>, newValue: D): void;
|
|
45
|
+
export declare function linkedSignalUpdateFn<S, D>(node: LinkedSignalNode<S, D>, updater: (value: D) => D): void;
|
|
46
|
+
export declare const LINKED_SIGNAL_NODE: Omit<LinkedSignalNode<unknown, unknown>, 'computation' | 'source' | 'sourceValue'>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { isDevMode } from '../../../core.js';
|
|
9
|
+
import { COMPUTING, ERRORED, UNSET } from './computed.js';
|
|
10
|
+
import { defaultEquals } from './equality.js';
|
|
11
|
+
import { consumerAfterComputation, consumerBeforeComputation, producerAccessed, producerMarkClean, producerUpdateValueVersion, REACTIVE_NODE, runPostProducerCreatedFn, setActiveConsumer, SIGNAL, } from './graph.js';
|
|
12
|
+
import { signalSetFn, signalUpdateFn } from './signal.js';
|
|
13
|
+
export function createLinkedSignal(sourceFn, computationFn, equalityFn) {
|
|
14
|
+
const node = Object.create(LINKED_SIGNAL_NODE);
|
|
15
|
+
node.source = sourceFn;
|
|
16
|
+
node.computation = computationFn;
|
|
17
|
+
if (equalityFn != undefined) {
|
|
18
|
+
node.equal = equalityFn;
|
|
19
|
+
}
|
|
20
|
+
const linkedSignalGetter = () => {
|
|
21
|
+
// Check if the value needs updating before returning it.
|
|
22
|
+
producerUpdateValueVersion(node);
|
|
23
|
+
// Record that someone looked at this signal.
|
|
24
|
+
producerAccessed(node);
|
|
25
|
+
if (node.value === ERRORED) {
|
|
26
|
+
throw node.error;
|
|
27
|
+
}
|
|
28
|
+
return node.value;
|
|
29
|
+
};
|
|
30
|
+
const getter = linkedSignalGetter;
|
|
31
|
+
getter[SIGNAL] = node;
|
|
32
|
+
if (isDevMode()) {
|
|
33
|
+
getter.toString = () => `[LinkedSignal${node.debugName ? ' (' + node.debugName + ')' : ''}: ${String(node.value)}]`;
|
|
34
|
+
}
|
|
35
|
+
runPostProducerCreatedFn(node);
|
|
36
|
+
return getter;
|
|
37
|
+
}
|
|
38
|
+
export function linkedSignalSetFn(node, newValue) {
|
|
39
|
+
producerUpdateValueVersion(node);
|
|
40
|
+
signalSetFn(node, newValue);
|
|
41
|
+
producerMarkClean(node);
|
|
42
|
+
}
|
|
43
|
+
export function linkedSignalUpdateFn(node, updater) {
|
|
44
|
+
producerUpdateValueVersion(node);
|
|
45
|
+
// update() on a linked signal can't work if the current state is ERRORED, as there's no value.
|
|
46
|
+
if (node.value === ERRORED) {
|
|
47
|
+
throw node.error;
|
|
48
|
+
}
|
|
49
|
+
signalUpdateFn(node, updater);
|
|
50
|
+
producerMarkClean(node);
|
|
51
|
+
}
|
|
52
|
+
// Note: Using an IIFE here to ensure that the spread assignment is not considered
|
|
53
|
+
// a side-effect, ending up preserving `LINKED_SIGNAL_NODE` and `REACTIVE_NODE`.
|
|
54
|
+
export const LINKED_SIGNAL_NODE = /* @__PURE__ */ (() => {
|
|
55
|
+
return {
|
|
56
|
+
...REACTIVE_NODE,
|
|
57
|
+
value: UNSET,
|
|
58
|
+
dirty: true,
|
|
59
|
+
error: null,
|
|
60
|
+
equal: defaultEquals,
|
|
61
|
+
kind: 'linkedSignal',
|
|
62
|
+
producerMustRecompute(node) {
|
|
63
|
+
// Force a recomputation if there's no current value, or if the current value is in the
|
|
64
|
+
// process of being calculated (which should throw an error).
|
|
65
|
+
return node.value === UNSET || node.value === COMPUTING;
|
|
66
|
+
},
|
|
67
|
+
producerRecomputeValue(node) {
|
|
68
|
+
if (node.value === COMPUTING) {
|
|
69
|
+
// Our computation somehow led to a cyclic read of itself.
|
|
70
|
+
throw new Error(isDevMode() ? 'Detected cycle in computations.' : '');
|
|
71
|
+
}
|
|
72
|
+
const oldValue = node.value;
|
|
73
|
+
node.value = COMPUTING;
|
|
74
|
+
const prevConsumer = consumerBeforeComputation(node);
|
|
75
|
+
let newValue;
|
|
76
|
+
let wasEqual = false;
|
|
77
|
+
try {
|
|
78
|
+
const newSourceValue = node.source();
|
|
79
|
+
const oldValueValid = oldValue !== UNSET && oldValue !== ERRORED;
|
|
80
|
+
const prev = oldValueValid
|
|
81
|
+
? {
|
|
82
|
+
source: node.sourceValue,
|
|
83
|
+
value: oldValue,
|
|
84
|
+
}
|
|
85
|
+
: undefined;
|
|
86
|
+
newValue = node.computation(newSourceValue, prev);
|
|
87
|
+
node.sourceValue = newSourceValue;
|
|
88
|
+
// We want to mark this node as errored if calling `equal` throws; however, we don't want
|
|
89
|
+
// to track any reactive reads inside `equal`.
|
|
90
|
+
setActiveConsumer(null);
|
|
91
|
+
wasEqual = oldValueValid && newValue !== ERRORED && node.equal(oldValue, newValue);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
newValue = ERRORED;
|
|
95
|
+
node.error = err;
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
consumerAfterComputation(node, prevConsumer);
|
|
99
|
+
}
|
|
100
|
+
if (wasEqual) {
|
|
101
|
+
// No change to `valueVersion` - old and new values are
|
|
102
|
+
// semantically equivalent.
|
|
103
|
+
node.value = oldValue;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
node.value = newValue;
|
|
107
|
+
node.version++;
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
})();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { type ValueEqualityFn } from './equality.js';
|
|
9
|
+
import { type ReactiveHookFn, type ReactiveNode, SIGNAL } from './graph.js';
|
|
10
|
+
export interface SignalNode<T> extends ReactiveNode {
|
|
11
|
+
value: T;
|
|
12
|
+
equal: ValueEqualityFn<T>;
|
|
13
|
+
}
|
|
14
|
+
export type SignalBaseGetter<T> = (() => T) & {
|
|
15
|
+
readonly [SIGNAL]: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type SignalSetter<T> = (newValue: T) => void;
|
|
18
|
+
export type SignalUpdater<T> = (updateFn: (value: T) => T) => void;
|
|
19
|
+
export interface SignalGetter<T> extends SignalBaseGetter<T> {
|
|
20
|
+
readonly [SIGNAL]: SignalNode<T>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a `Signal` getter, setter, and updater function.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createSignal<T>(initialValue: T, equal?: ValueEqualityFn<T>): [SignalGetter<T>, SignalSetter<T>, SignalUpdater<T>];
|
|
26
|
+
export declare function setPostSignalSetFn(fn: ReactiveHookFn | null): ReactiveHookFn | null;
|
|
27
|
+
export declare function signalGetFn<T>(node: SignalNode<T>): T;
|
|
28
|
+
export declare function signalSetFn<T>(node: SignalNode<T>, newValue: T): void;
|
|
29
|
+
export declare function signalUpdateFn<T>(node: SignalNode<T>, updater: (value: T) => T): void;
|
|
30
|
+
export declare function runPostSignalSetFn<T>(node: SignalNode<T>): void;
|
|
31
|
+
export declare const SIGNAL_NODE: SignalNode<unknown>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { isDevMode } from '../../../core.js';
|
|
9
|
+
import { defaultEquals } from './equality.js';
|
|
10
|
+
import { throwInvalidWriteToSignalError } from './errors.js';
|
|
11
|
+
import { producerAccessed, producerIncrementEpoch, producerNotifyConsumers, producerUpdatesAllowed, REACTIVE_NODE, runPostProducerCreatedFn, SIGNAL, } from './graph.js';
|
|
12
|
+
/**
|
|
13
|
+
* If set, called after `WritableSignal`s are updated.
|
|
14
|
+
*
|
|
15
|
+
* This hook can be used to achieve various effects, such as running effects synchronously as part
|
|
16
|
+
* of setting a signal.
|
|
17
|
+
*/
|
|
18
|
+
let postSignalSetFn = null;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a `Signal` getter, setter, and updater function.
|
|
21
|
+
*/
|
|
22
|
+
export function createSignal(initialValue, equal) {
|
|
23
|
+
const node = Object.create(SIGNAL_NODE);
|
|
24
|
+
node.value = initialValue;
|
|
25
|
+
if (equal !== undefined) {
|
|
26
|
+
node.equal = equal;
|
|
27
|
+
}
|
|
28
|
+
const getter = (() => signalGetFn(node));
|
|
29
|
+
getter[SIGNAL] = node;
|
|
30
|
+
if (isDevMode()) {
|
|
31
|
+
getter.toString = () => `[Signal${node.debugName ? ' (' + node.debugName + ')' : ''}: ${String(node.value)}]`;
|
|
32
|
+
}
|
|
33
|
+
runPostProducerCreatedFn(node);
|
|
34
|
+
const set = (newValue) => signalSetFn(node, newValue);
|
|
35
|
+
const update = (updateFn) => signalUpdateFn(node, updateFn);
|
|
36
|
+
return [getter, set, update];
|
|
37
|
+
}
|
|
38
|
+
export function setPostSignalSetFn(fn) {
|
|
39
|
+
const prev = postSignalSetFn;
|
|
40
|
+
postSignalSetFn = fn;
|
|
41
|
+
return prev;
|
|
42
|
+
}
|
|
43
|
+
export function signalGetFn(node) {
|
|
44
|
+
producerAccessed(node);
|
|
45
|
+
return node.value;
|
|
46
|
+
}
|
|
47
|
+
export function signalSetFn(node, newValue) {
|
|
48
|
+
if (!producerUpdatesAllowed()) {
|
|
49
|
+
throwInvalidWriteToSignalError(node);
|
|
50
|
+
}
|
|
51
|
+
if (!node.equal(node.value, newValue)) {
|
|
52
|
+
node.value = newValue;
|
|
53
|
+
signalValueChanged(node);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function signalUpdateFn(node, updater) {
|
|
57
|
+
if (!producerUpdatesAllowed()) {
|
|
58
|
+
throwInvalidWriteToSignalError(node);
|
|
59
|
+
}
|
|
60
|
+
signalSetFn(node, updater(node.value));
|
|
61
|
+
}
|
|
62
|
+
export function runPostSignalSetFn(node) {
|
|
63
|
+
postSignalSetFn?.(node);
|
|
64
|
+
}
|
|
65
|
+
// Note: Using an IIFE here to ensure that the spread assignment is not considered
|
|
66
|
+
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
|
|
67
|
+
export const SIGNAL_NODE = /* @__PURE__ */ (() => {
|
|
68
|
+
return {
|
|
69
|
+
...REACTIVE_NODE,
|
|
70
|
+
equal: defaultEquals,
|
|
71
|
+
value: undefined,
|
|
72
|
+
kind: 'signal',
|
|
73
|
+
};
|
|
74
|
+
})();
|
|
75
|
+
function signalValueChanged(node) {
|
|
76
|
+
node.version++;
|
|
77
|
+
producerIncrementEpoch();
|
|
78
|
+
producerNotifyConsumers(node);
|
|
79
|
+
postSignalSetFn?.(node);
|
|
80
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Execute an arbitrary function in a non-reactive (non-tracking) context. The executed function
|
|
10
|
+
* can, optionally, return a value.
|
|
11
|
+
*/
|
|
12
|
+
export declare function untracked<T>(nonReactiveReadsFn: () => T): T;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { setActiveConsumer } from './graph.js';
|
|
9
|
+
/**
|
|
10
|
+
* Execute an arbitrary function in a non-reactive (non-tracking) context. The executed function
|
|
11
|
+
* can, optionally, return a value.
|
|
12
|
+
*/
|
|
13
|
+
export function untracked(nonReactiveReadsFn) {
|
|
14
|
+
const prevConsumer = setActiveConsumer(null);
|
|
15
|
+
// We are not trying to catch any particular errors here, just making sure that the consumers
|
|
16
|
+
// stack is restored in case of errors.
|
|
17
|
+
try {
|
|
18
|
+
return nonReactiveReadsFn();
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
setActiveConsumer(prevConsumer);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright Google LLC All Rights Reserved.
|
|
4
4
|
*
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
8
|
import { type ReactiveNode, SIGNAL } from './graph.js';
|
|
9
9
|
/**
|
|
@@ -34,7 +34,6 @@ export interface Watch {
|
|
|
34
34
|
[SIGNAL]: WatchNode;
|
|
35
35
|
}
|
|
36
36
|
export interface WatchNode extends ReactiveNode {
|
|
37
|
-
hasRun: boolean;
|
|
38
37
|
fn: ((onCleanup: WatchCleanupRegisterFn) => void) | null;
|
|
39
38
|
schedule: ((watch: Watch) => void) | null;
|
|
40
39
|
cleanupFn: WatchCleanupFn;
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Copyright Google LLC All Rights Reserved.
|
|
4
4
|
*
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
+
import { isDevMode } from '../../../core.js';
|
|
8
9
|
import { consumerAfterComputation, consumerBeforeComputation, consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, isInNotificationPhase, REACTIVE_NODE, SIGNAL, } from './graph.js';
|
|
9
10
|
export function createWatch(fn, schedule, allowSignalWrites) {
|
|
10
11
|
const node = Object.create(WATCH_NODE);
|
|
@@ -35,13 +36,15 @@ export function createWatch(fn, schedule, allowSignalWrites) {
|
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
38
|
if (isInNotificationPhase()) {
|
|
38
|
-
throw new Error(
|
|
39
|
+
throw new Error(isDevMode()
|
|
40
|
+
? 'Schedulers cannot synchronously execute watches while scheduling.'
|
|
41
|
+
: '');
|
|
39
42
|
}
|
|
40
43
|
node.dirty = false;
|
|
41
|
-
if (node.
|
|
44
|
+
if (node.version > 0 && !consumerPollProducersForChange(node)) {
|
|
42
45
|
return;
|
|
43
46
|
}
|
|
44
|
-
node.
|
|
47
|
+
node.version++;
|
|
45
48
|
const prevConsumer = consumerBeforeComputation(node);
|
|
46
49
|
try {
|
|
47
50
|
node.cleanupFn();
|
|
@@ -62,15 +65,18 @@ export function createWatch(fn, schedule, allowSignalWrites) {
|
|
|
62
65
|
return node.ref;
|
|
63
66
|
}
|
|
64
67
|
const NOOP_CLEANUP_FN = () => { };
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
68
|
+
// Note: Using an IIFE here to ensure that the spread assignment is not considered
|
|
69
|
+
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
|
|
70
|
+
const WATCH_NODE = /* @__PURE__ */ (() => {
|
|
71
|
+
return {
|
|
72
|
+
...REACTIVE_NODE,
|
|
73
|
+
consumerIsAlwaysLive: true,
|
|
74
|
+
consumerAllowSignalWrites: false,
|
|
75
|
+
consumerMarkedDirty: (node) => {
|
|
76
|
+
if (node.schedule !== null) {
|
|
77
|
+
node.schedule(node.ref);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
cleanupFn: NOOP_CLEANUP_FN,
|
|
81
|
+
};
|
|
82
|
+
})();
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/** biome-ignore-all lint: <explanation> */
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
8
|
+
*/
|
|
9
|
+
import type { SignalsInjector } from '../../../signals/api.js';
|
|
10
|
+
import type { Signal, ValueEqualityFn } from '../api.js';
|
|
11
|
+
import type { WritableSignal } from '../signal.js';
|
|
12
|
+
/** Error thrown when a `Resource` dependency of another resource errors. */
|
|
13
|
+
export declare class ResourceDependencyError extends Error {
|
|
14
|
+
/** The dependency that errored. */
|
|
15
|
+
readonly dependency: Resource<unknown>;
|
|
16
|
+
constructor(dependency: Resource<unknown>);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Special status codes that can be thrown from a resource's `params` or `request` function to
|
|
20
|
+
* indicate that the resource should transition to that status.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ResourceParamsStatus extends Error {
|
|
23
|
+
private readonly _brand;
|
|
24
|
+
private constructor();
|
|
25
|
+
/** Status code that transitions the resource to `idle` status. */
|
|
26
|
+
static readonly IDLE: ResourceParamsStatus;
|
|
27
|
+
/** Status code that transitions the resource to `loading` status. */
|
|
28
|
+
static readonly LOADING: ResourceParamsStatus;
|
|
29
|
+
}
|
|
30
|
+
/** Context received by a resource's `params` or `request` function. */
|
|
31
|
+
export interface ResourceParamsContext {
|
|
32
|
+
/**
|
|
33
|
+
* Chains the current params off of the value of another resource, returning the value
|
|
34
|
+
* of the other resource if it is available, or propagating the status to the current resource by
|
|
35
|
+
* throwing the appropriate status code if the value is not available.
|
|
36
|
+
*/
|
|
37
|
+
readonly chain: <T>(resource: Resource<T>) => T;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* String value capturing the status of a `Resource`.
|
|
41
|
+
*
|
|
42
|
+
* Possible statuses are:
|
|
43
|
+
*
|
|
44
|
+
* `idle` - The resource has no valid request and will not perform any loading. `value()` will be
|
|
45
|
+
* `undefined`.
|
|
46
|
+
*
|
|
47
|
+
* `loading` - The resource is currently loading a new value as a result of a change in its reactive
|
|
48
|
+
* dependencies. `value()` will be `undefined`.
|
|
49
|
+
*
|
|
50
|
+
* `reloading` - The resource is currently reloading a fresh value for the same reactive
|
|
51
|
+
* dependencies. `value()` will continue to return the previously fetched value during the reloading
|
|
52
|
+
* operation.
|
|
53
|
+
*
|
|
54
|
+
* `error` - Loading failed with an error. `value()` will be `undefined`.
|
|
55
|
+
*
|
|
56
|
+
* `resolved` - Loading has completed and the resource has the value returned from the loader.
|
|
57
|
+
*
|
|
58
|
+
* `local` - The resource's value was set locally via `.set()` or `.update()`.
|
|
59
|
+
*
|
|
60
|
+
* @experimental
|
|
61
|
+
*/
|
|
62
|
+
export type ResourceStatus = 'idle' | 'error' | 'loading' | 'reloading' | 'resolved' | 'local';
|
|
63
|
+
/**
|
|
64
|
+
* A Resource is an asynchronous dependency (for example, the results of an API call) that is
|
|
65
|
+
* managed and delivered through signals.
|
|
66
|
+
*
|
|
67
|
+
* The usual way of creating a `Resource` is through the `resource` function, but various other APIs
|
|
68
|
+
* may present `Resource` instances to describe their own concepts.
|
|
69
|
+
*
|
|
70
|
+
* @experimental
|
|
71
|
+
*/
|
|
72
|
+
export interface Resource<T> {
|
|
73
|
+
/**
|
|
74
|
+
* The current value of the `Resource`, or throws an error if the resource is in an error state.
|
|
75
|
+
*/
|
|
76
|
+
readonly value: Signal<T>;
|
|
77
|
+
/**
|
|
78
|
+
* The current status of the `Resource`, which describes what the resource is currently doing and
|
|
79
|
+
* what can be expected of its `value`.
|
|
80
|
+
*/
|
|
81
|
+
readonly status: Signal<ResourceStatus>;
|
|
82
|
+
/**
|
|
83
|
+
* When in the `error` state, this returns the last known error from the `Resource`.
|
|
84
|
+
*/
|
|
85
|
+
readonly error: Signal<Error | undefined>;
|
|
86
|
+
/**
|
|
87
|
+
* Whether this resource is loading a new value (or reloading the existing one).
|
|
88
|
+
*/
|
|
89
|
+
readonly isLoading: Signal<boolean>;
|
|
90
|
+
/**
|
|
91
|
+
* The current state of this resource, represented as a `ResourceSnapshot`.
|
|
92
|
+
*/
|
|
93
|
+
readonly snapshot: Signal<ResourceSnapshot<T>>;
|
|
94
|
+
/**
|
|
95
|
+
* Whether this resource has a valid current value.
|
|
96
|
+
*
|
|
97
|
+
* This function is reactive.
|
|
98
|
+
*/
|
|
99
|
+
hasValue(this: T extends undefined ? this : never): this is Resource<Exclude<T, undefined>>;
|
|
100
|
+
hasValue(): boolean;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A `Resource` with a mutable value.
|
|
104
|
+
*
|
|
105
|
+
* Overwriting the value of a resource sets it to the 'local' state.
|
|
106
|
+
*
|
|
107
|
+
* @experimental
|
|
108
|
+
*/
|
|
109
|
+
export interface WritableResource<T> extends Resource<T> {
|
|
110
|
+
readonly value: WritableSignal<T>;
|
|
111
|
+
hasValue(this: T extends undefined ? this : never): this is WritableResource<Exclude<T, undefined>>;
|
|
112
|
+
hasValue(): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Convenience wrapper for `value.set`.
|
|
115
|
+
*/
|
|
116
|
+
set(value: T): void;
|
|
117
|
+
/**
|
|
118
|
+
* Convenience wrapper for `value.update`.
|
|
119
|
+
*/
|
|
120
|
+
update(updater: (value: T) => T): void;
|
|
121
|
+
asReadonly(): Resource<T>;
|
|
122
|
+
/**
|
|
123
|
+
* Instructs the resource to re-load any asynchronous dependency it may have.
|
|
124
|
+
*
|
|
125
|
+
* Note that the resource will not enter its reloading state until the actual backend request is
|
|
126
|
+
* made.
|
|
127
|
+
*
|
|
128
|
+
* @returns true if a reload was initiated, false if a reload was unnecessary or unsupported
|
|
129
|
+
*/
|
|
130
|
+
reload(): boolean;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* A `WritableResource` created through the `resource` function.
|
|
134
|
+
*
|
|
135
|
+
* @experimental
|
|
136
|
+
*/
|
|
137
|
+
export interface ResourceRef<T> extends WritableResource<T> {
|
|
138
|
+
hasValue(this: T extends undefined ? this : never): this is ResourceRef<Exclude<T, undefined>>;
|
|
139
|
+
hasValue(): boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Manually destroy the resource, which cancels pending requests and returns it to `idle` state.
|
|
142
|
+
*/
|
|
143
|
+
destroy(): void;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parameter to a `ResourceLoader` which gives the request and other options for the current loading
|
|
147
|
+
* operation.
|
|
148
|
+
*
|
|
149
|
+
* @experimental
|
|
150
|
+
*/
|
|
151
|
+
export interface ResourceLoaderParams<R> {
|
|
152
|
+
params: NoInfer<Exclude<R, undefined>>;
|
|
153
|
+
abortSignal: AbortSignal;
|
|
154
|
+
previous: {
|
|
155
|
+
status: ResourceStatus;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Loading function for a `Resource`.
|
|
160
|
+
*
|
|
161
|
+
* @experimental
|
|
162
|
+
*/
|
|
163
|
+
export type ResourceLoader<T, R> = (param: ResourceLoaderParams<R>) => PromiseLike<T>;
|
|
164
|
+
/**
|
|
165
|
+
* Streaming loader for a `Resource`.
|
|
166
|
+
*
|
|
167
|
+
* @experimental
|
|
168
|
+
*/
|
|
169
|
+
export type ResourceStreamingLoader<T, R> = (param: ResourceLoaderParams<R>) => PromiseLike<Signal<ResourceStreamItem<T>>>;
|
|
170
|
+
/**
|
|
171
|
+
* Options to the `resource` function, for creating a resource.
|
|
172
|
+
*
|
|
173
|
+
* @experimental
|
|
174
|
+
*/
|
|
175
|
+
export interface BaseResourceOptions<T, R> {
|
|
176
|
+
/**
|
|
177
|
+
* A reactive function which determines the request to be made. Whenever the request changes, the
|
|
178
|
+
* loader will be triggered to fetch a new value for the resource.
|
|
179
|
+
*
|
|
180
|
+
* If a params function isn't provided, the loader won't rerun unless the resource is reloaded.
|
|
181
|
+
*/
|
|
182
|
+
params?: (ctx: ResourceParamsContext) => R;
|
|
183
|
+
/**
|
|
184
|
+
* The value which will be returned from the resource when a server value is unavailable, such as
|
|
185
|
+
* when the resource is still loading.
|
|
186
|
+
*/
|
|
187
|
+
defaultValue?: NoInfer<T>;
|
|
188
|
+
/**
|
|
189
|
+
* Equality function used to compare the return value of the loader.
|
|
190
|
+
*/
|
|
191
|
+
equal?: ValueEqualityFn<T>;
|
|
192
|
+
/**
|
|
193
|
+
* Overrides the `Injector` used by `resource`.
|
|
194
|
+
*/
|
|
195
|
+
injector?: SignalsInjector;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Options to the `resource` function, for creating a resource.
|
|
199
|
+
*
|
|
200
|
+
* @experimental
|
|
201
|
+
*/
|
|
202
|
+
export interface PromiseResourceOptions<T, R> extends BaseResourceOptions<T, R> {
|
|
203
|
+
/**
|
|
204
|
+
* Loading function which returns a `Promise` of the resource's value for a given request.
|
|
205
|
+
*/
|
|
206
|
+
loader: ResourceLoader<T, R>;
|
|
207
|
+
/**
|
|
208
|
+
* Cannot specify `stream` and `loader` at the same time.
|
|
209
|
+
*/
|
|
210
|
+
stream?: never;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Options to the `resource` function, for creating a resource.
|
|
214
|
+
*
|
|
215
|
+
* @experimental
|
|
216
|
+
*/
|
|
217
|
+
export interface StreamingResourceOptions<T, R> extends BaseResourceOptions<T, R> {
|
|
218
|
+
/**
|
|
219
|
+
* Loading function which returns a `Promise` of a signal of the resource's value for a given
|
|
220
|
+
* request, which can change over time as new values are received from a stream.
|
|
221
|
+
*/
|
|
222
|
+
stream: ResourceStreamingLoader<T, R>;
|
|
223
|
+
/**
|
|
224
|
+
* Cannot specify `stream` and `loader` at the same time.
|
|
225
|
+
*/
|
|
226
|
+
loader?: never;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* @experimental
|
|
230
|
+
*/
|
|
231
|
+
export type ResourceOptions<T, R> = (PromiseResourceOptions<T, R> | StreamingResourceOptions<T, R>) & {
|
|
232
|
+
/**
|
|
233
|
+
* A debug name for the reactive node. Used in Angular DevTools to identify the node.
|
|
234
|
+
*/
|
|
235
|
+
debugName?: string;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* @experimental
|
|
239
|
+
*/
|
|
240
|
+
export type ResourceStreamItem<T> = {
|
|
241
|
+
value: T;
|
|
242
|
+
} | {
|
|
243
|
+
error: Error;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* An explicit representation of a resource's state.
|
|
247
|
+
*
|
|
248
|
+
* @experimental
|
|
249
|
+
* @see [Resource composition with snapshots](guide/signals/resource#resource-composition-with-snapshots)
|
|
250
|
+
*/
|
|
251
|
+
export type ResourceSnapshot<T> = {
|
|
252
|
+
readonly status: 'idle';
|
|
253
|
+
readonly value: T;
|
|
254
|
+
} | {
|
|
255
|
+
readonly status: 'loading' | 'reloading';
|
|
256
|
+
readonly value: T;
|
|
257
|
+
} | {
|
|
258
|
+
readonly status: 'resolved' | 'local';
|
|
259
|
+
readonly value: T;
|
|
260
|
+
} | {
|
|
261
|
+
readonly status: 'error';
|
|
262
|
+
readonly error: Error;
|
|
263
|
+
};
|
|
264
|
+
/** Options for `debounced`. */
|
|
265
|
+
export interface DebouncedOptions<T> {
|
|
266
|
+
/** The `Injector` to use for the debounced resource. */
|
|
267
|
+
injector?: SignalsInjector;
|
|
268
|
+
/** The equality function to use for comparing values. */
|
|
269
|
+
equal?: ValueEqualityFn<T>;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Represents the wait condition for item debouncing.
|
|
273
|
+
* Can be a number of milliseconds or a function that returns a Promise.
|
|
274
|
+
*/
|
|
275
|
+
export type DebounceTimer<T> = number | ((value: T, lastValue: ResourceSnapshot<T>) => Promise<void> | void);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/** biome-ignore-all lint: <explanation> */
|
|
3
|
+
/** Error thrown when a `Resource` dependency of another resource errors. */
|
|
4
|
+
export class ResourceDependencyError extends Error {
|
|
5
|
+
/** The dependency that errored. */
|
|
6
|
+
dependency;
|
|
7
|
+
constructor(dependency) {
|
|
8
|
+
super('Dependency error', { cause: dependency.error() });
|
|
9
|
+
this.name = 'ResourceDependencyError';
|
|
10
|
+
this.dependency = dependency;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Special status codes that can be thrown from a resource's `params` or `request` function to
|
|
15
|
+
* indicate that the resource should transition to that status.
|
|
16
|
+
*/
|
|
17
|
+
export class ResourceParamsStatus extends Error {
|
|
18
|
+
_brand;
|
|
19
|
+
constructor(msg) {
|
|
20
|
+
super(msg);
|
|
21
|
+
}
|
|
22
|
+
/** Status code that transitions the resource to `idle` status. */
|
|
23
|
+
static IDLE = new ResourceParamsStatus('IDLE');
|
|
24
|
+
/** Status code that transitions the resource to `loading` status. */
|
|
25
|
+
static LOADING = new ResourceParamsStatus('LOADING');
|
|
26
|
+
}
|