@tstdl/base 0.90.30 → 0.90.32

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.
@@ -186,17 +186,25 @@ let ApiGateway = class ApiGateway {
186
186
  getToken: async () => this.requestTokenProvider.getToken(requestContext)
187
187
  };
188
188
  const result = await context.endpoint.implementation(requestContext);
189
- if (result instanceof HttpServerResponse) {
190
- return result;
189
+ const response = (result instanceof HttpServerResponse)
190
+ ? result
191
+ : new HttpServerResponse({
192
+ body: isUint8Array(result) ? { buffer: result }
193
+ : isBlob(result) ? { stream: result.stream() }
194
+ : isReadableStream(result) ? { stream: result }
195
+ : (result instanceof ServerSentEventsSource) ? { events: result }
196
+ : (context.endpoint.definition.result == String) ? { text: result }
197
+ : { json: result }
198
+ });
199
+ if (isUndefined(response.headers.contentType)) {
200
+ response.headers.contentType =
201
+ (isDefined(response.body?.json)) ? 'application/json; charset=utf-8'
202
+ : (isDefined(response.body?.text)) ? 'text/plain; charset=utf-8'
203
+ : (isDefined(response.body?.buffer)) ? 'application/octet-stream'
204
+ : (isDefined(response.body?.stream)) ? 'application/octet-stream'
205
+ : (isDefined(response.body?.events)) ? 'text/event-stream'
206
+ : undefined;
191
207
  }
192
- const response = new HttpServerResponse({
193
- body: isUint8Array(result) ? { buffer: result }
194
- : isBlob(result) ? { stream: result.stream() }
195
- : isReadableStream(result) ? { stream: result }
196
- : (result instanceof ServerSentEventsSource) ? { events: result }
197
- : (context.endpoint.definition.result == String) ? { text: result }
198
- : { json: result }
199
- });
200
208
  return response;
201
209
  }
202
210
  async getBody(request, options, schema) {
@@ -141,21 +141,6 @@ function getResponder(httpResponse) {
141
141
  return respond;
142
142
  }
143
143
  function writeHeaders(response, httpResponse) {
144
- if (isDefined(response.body?.json)) {
145
- httpResponse.setHeader('Content-Type', 'application/json; charset=utf-8');
146
- }
147
- else if (isDefined(response.body?.text)) {
148
- httpResponse.setHeader('Content-Type', 'text/plain; charset=utf-8');
149
- }
150
- else if (isDefined(response.body?.buffer)) {
151
- httpResponse.setHeader('Content-Type', 'application/octet-stream');
152
- }
153
- else if (isDefined(response.body?.stream)) {
154
- httpResponse.setHeader('Content-Type', 'application/octet-stream');
155
- }
156
- else if (isDefined(response.body?.events)) {
157
- httpResponse.setHeader('Content-Type', 'text/event-stream');
158
- }
159
144
  for (const [name, value] of response.headers.normalizedEntries()) {
160
145
  httpResponse.setHeader(name, value);
161
146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.90.30",
3
+ "version": "0.90.32",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -149,7 +149,7 @@
149
149
  "mongodb": "^6.2",
150
150
  "nodemailer": "^6.9",
151
151
  "playwright": "^1.39",
152
- "preact": "^10.18",
152
+ "preact": "^10.19",
153
153
  "preact-render-to-string": "^6.3",
154
154
  "undici": "^5.27",
155
155
  "urlpattern-polyfill": "^9.0"
@@ -1,5 +1,5 @@
1
1
  import type { Decorator } from '../../reflection/index.js';
2
2
  import type { ValueSchema, ValueSchemaOptions } from '../types/types.js';
3
3
  export type LiteralOptions = ValueSchemaOptions;
4
- export declare function literal<T>(value: T, options?: LiteralOptions): ValueSchema<T>;
4
+ export declare function literal<const T>(value: T, options?: LiteralOptions): ValueSchema<T>;
5
5
  export declare function Literal(value: any): Decorator<'property' | 'accessor'>;
@@ -1,10 +1,13 @@
1
1
  import { computed as actualComputed } from './api.js';
2
2
  export function computedWithDependencies(computation, dependencies, options = {}) {
3
+ if (dependencies.length == 0) {
4
+ return actualComputed(computation, options);
5
+ }
3
6
  function computationWithDependencies() {
4
7
  for (let i = 0; i < dependencies.length; i++) { // eslint-disable-line @typescript-eslint/prefer-for-of
5
8
  dependencies[i]();
6
9
  }
7
10
  return computation();
8
11
  }
9
- return actualComputed((dependencies.length == 0) ? computation : computationWithDependencies, options);
12
+ return actualComputed(computationWithDependencies, options);
10
13
  }
package/signals/defer.js CHANGED
@@ -1,11 +1,8 @@
1
- import { isUndefined } from '../utils/type-guards.js';
2
1
  import { computed, untracked } from './api.js';
3
2
  export function defer(signalFactory) {
4
- let source;
5
- return computed(() => {
6
- if (isUndefined(source)) {
7
- source = untracked(signalFactory);
8
- }
9
- return source();
10
- });
3
+ let computation = () => {
4
+ computation = untracked(signalFactory);
5
+ return computation();
6
+ };
7
+ return computed(() => computation());
11
8
  }
@@ -1,10 +1,13 @@
1
1
  import { effect as actualEffect } from './api.js';
2
2
  export function effectWithDependencies(effectFn, dependencies, options) {
3
+ if (dependencies.length == 0) {
4
+ return actualEffect(effectFn, options);
5
+ }
3
6
  function effectFnWithDependencies(onCleanup) {
4
7
  for (let i = 0; i < dependencies.length; i++) { // eslint-disable-line @typescript-eslint/prefer-for-of
5
8
  dependencies[i]();
6
9
  }
7
10
  effectFn(onCleanup);
8
11
  }
9
- return actualEffect((dependencies.length == 0) ? effectFn : effectFnWithDependencies, options);
12
+ return actualEffect(effectFnWithDependencies, options);
10
13
  }
@@ -10,7 +10,5 @@
10
10
  * to disallow certain code from running inside a reactive context (see {@link toSignal}).
11
11
  *
12
12
  * @param debugFn a reference to the function making the assertion (used for the error message).
13
- *
14
- * @publicApi
15
13
  */
16
14
  export declare function assertNotInReactiveContext(debugFn: Function, extraContext?: string): void;
@@ -11,8 +11,6 @@ import { getActiveConsumer } from './graph.js';
11
11
  * to disallow certain code from running inside a reactive context (see {@link toSignal}).
12
12
  *
13
13
  * @param debugFn a reference to the function making the assertion (used for the error message).
14
- *
15
- * @publicApi
16
14
  */
17
15
  export function assertNotInReactiveContext(debugFn, extraContext) {
18
16
  // Taking a `Function` instead of a string name here prevents the un-minified name of the function
@@ -5,10 +5,10 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { SIGNAL } from '../symbol.js';
9
8
  import type { Signal } from './api.js';
10
9
  import type { ValueEqualityFn } from './equality.js';
11
10
  import type { ReactiveNode } from './graph.js';
11
+ import { SIGNAL } from './graph.js';
12
12
  /**
13
13
  * A computation, which derives a value from a declarative reactive expression.
14
14
  *
@@ -1,13 +1,6 @@
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.io/license
7
- */
8
- import { SIGNAL } from '../symbol.js';
1
+ /* eslint-disable */
9
2
  import { defaultEquals } from './equality.js';
10
- import { consumerAfterComputation, consumerBeforeComputation, producerAccessed, producerUpdateValueVersion, REACTIVE_NODE } from './graph.js';
3
+ import { consumerAfterComputation, consumerBeforeComputation, producerAccessed, producerUpdateValueVersion, REACTIVE_NODE, SIGNAL } from './graph.js';
11
4
  /**
12
5
  * Create a computed signal which derives a reactive value from an expression.
13
6
  */
@@ -34,7 +34,7 @@ export class TstdlEffectScheduler {
34
34
  }
35
35
  }
36
36
  /**
37
- * Core reactive node for an Angular effect.
37
+ * Core reactive node for an effect.
38
38
  *
39
39
  * `EffectHandle` combines the reactive graph's `Watch` base node for effects with the framework's
40
40
  * scheduling abstraction (`EffectScheduler`) as well as automatic cleanup via `DestroyRef` if
@@ -50,7 +50,12 @@ class EffectHandle {
50
50
  this.watcher = createWatch((onCleanup) => this.runEffect(onCleanup), () => this.schedule(), allowSignalWrites);
51
51
  }
52
52
  runEffect(onCleanup) {
53
- this.effectFn(onCleanup);
53
+ try {
54
+ this.effectFn(onCleanup);
55
+ }
56
+ catch (err) {
57
+ queueMicrotask(() => { throw err; });
58
+ }
54
59
  }
55
60
  run() {
56
61
  this.watcher.run();
@@ -58,9 +63,6 @@ class EffectHandle {
58
63
  schedule() {
59
64
  this.scheduler.scheduleEffect(this);
60
65
  }
61
- notify() {
62
- this.watcher.notify();
63
- }
64
66
  destroy() {
65
67
  this.watcher.destroy();
66
68
  // Note: if the effect is currently scheduled, it's not un-scheduled, and so the scheduler will
@@ -72,8 +74,9 @@ const effectScheduler = new TstdlEffectScheduler();
72
74
  * Create a global `Effect` for the given reactive function.
73
75
  */
74
76
  export function effect(effectFn, options) {
75
- assertNotInReactiveContext(effect, 'Call `effect` outside of a reactive context. For example, schedule the effect inside the component constructor.');
77
+ assertNotInReactiveContext(effect, 'Call `effect` outside of a reactive context. For example, schedule the ' +
78
+ 'effect inside the component constructor.');
76
79
  const handle = new EffectHandle(effectScheduler, effectFn, options?.allowSignalWrites ?? false);
77
- handle.notify();
80
+ handle.watcher.notify();
78
81
  return handle;
79
82
  }
@@ -1,10 +1,4 @@
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.io/license
7
- */
1
+ /* eslint-disable */
8
2
  /**
9
3
  * The default equality function used for `signal` and `computed`, which uses referential equality.
10
4
  */
@@ -1,9 +1,2 @@
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.io/license
7
- */
8
1
  export declare function throwInvalidWriteToSignalError(): void;
9
2
  export declare function setThrowInvalidWriteToSignalError(fn: () => never): void;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable */
1
2
  /**
2
3
  * @license
3
4
  * Copyright Google LLC All Rights Reserved.
@@ -1,11 +1,5 @@
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.io/license
7
- */
8
1
  import { SIGNAL } from '../symbol.js';
2
+ export { SIGNAL };
9
3
  type Version = number & {
10
4
  __brand: 'Version';
11
5
  };
@@ -37,6 +31,13 @@ export interface ReactiveNode {
37
31
  * previous value (by whatever definition of equality is in use).
38
32
  */
39
33
  version: Version;
34
+ /**
35
+ * Epoch at which this node is verified to be clean.
36
+ *
37
+ * This allows skipping of some polling operations in the case where no signals have been set
38
+ * since this node was last read.
39
+ */
40
+ lastCleanEpoch: Version;
40
41
  /**
41
42
  * Whether this node (in its consumer capacity) is dirty.
42
43
  *
@@ -110,6 +111,12 @@ export interface ReactiveNode {
110
111
  * Called by implementations when a producer's signal is read.
111
112
  */
112
113
  export declare function producerAccessed(node: ReactiveNode): void;
114
+ /**
115
+ * Increment the global epoch counter.
116
+ *
117
+ * Called by source producers (that is, not computeds) whenever their values change.
118
+ */
119
+ export declare function producerIncrementEpoch(): void;
113
120
  /**
114
121
  * Ensure this producer's `version` is up-to-date.
115
122
  */
@@ -147,4 +154,3 @@ export declare function consumerPollProducersForChange(node: ReactiveNode): bool
147
154
  * Disconnect this consumer from the graph.
148
155
  */
149
156
  export declare function consumerDestroy(node: ReactiveNode): void;
150
- export {};
@@ -1,3 +1,6 @@
1
+ /* eslint-disable */
2
+ import { SIGNAL } from '../symbol.js';
3
+ export { SIGNAL };
1
4
  /**
2
5
  * @license
3
6
  * Copyright Google LLC All Rights Reserved.
@@ -5,7 +8,6 @@
5
8
  * Use of this source code is governed by an MIT-style license that can be
6
9
  * found in the LICENSE file at https://angular.io/license
7
10
  */
8
- import { SIGNAL } from '../symbol.js';
9
11
  /**
10
12
  * The currently active consumer `ReactiveNode`, if running code in a reactive context.
11
13
  *
@@ -13,6 +15,10 @@ import { SIGNAL } from '../symbol.js';
13
15
  */
14
16
  let activeConsumer = null;
15
17
  let inNotificationPhase = false;
18
+ /**
19
+ * Global epoch counter. Incremented whenever a source signal is set.
20
+ */
21
+ let epoch = 1;
16
22
  export function setActiveConsumer(consumer) {
17
23
  const prev = activeConsumer;
18
24
  activeConsumer = consumer;
@@ -29,6 +35,7 @@ export function isReactive(value) {
29
35
  }
30
36
  export const REACTIVE_NODE = {
31
37
  version: 0,
38
+ lastCleanEpoch: 0,
32
39
  dirty: false,
33
40
  producerNode: undefined,
34
41
  producerLastReadVersion: undefined,
@@ -48,7 +55,7 @@ export const REACTIVE_NODE = {
48
55
  */
49
56
  export function producerAccessed(node) {
50
57
  if (inNotificationPhase) {
51
- throw new Error('Assertion error: signal read during notification phase');
58
+ throw new Error(`Assertion error: signal read during notification phase`);
52
59
  }
53
60
  if (activeConsumer === null) {
54
61
  // Accessed outside of a reactive context, so nothing to record.
@@ -83,6 +90,14 @@ export function producerAccessed(node) {
83
90
  }
84
91
  activeConsumer.producerLastReadVersion[idx] = node.version;
85
92
  }
93
+ /**
94
+ * Increment the global epoch counter.
95
+ *
96
+ * Called by source producers (that is, not computeds) whenever their values change.
97
+ */
98
+ export function producerIncrementEpoch() {
99
+ epoch++;
100
+ }
86
101
  /**
87
102
  * Ensure this producer's `version` is up-to-date.
88
103
  */
@@ -92,15 +107,23 @@ export function producerUpdateValueVersion(node) {
92
107
  // is guaranteed to be up-to-date.
93
108
  return;
94
109
  }
110
+ if (!node.dirty && node.lastCleanEpoch === epoch) {
111
+ // Even non-live consumers can skip polling if they previously found themselves to be clean at
112
+ // the current epoch, since their dependencies could not possibly have changed (such a change
113
+ // would've increased the epoch).
114
+ return;
115
+ }
95
116
  if (!node.producerMustRecompute(node) && !consumerPollProducersForChange(node)) {
96
117
  // None of our producers report a change since the last time they were read, so no
97
118
  // recomputation of our value is necessary, and we can consider ourselves clean.
98
119
  node.dirty = false;
120
+ node.lastCleanEpoch = epoch;
99
121
  return;
100
122
  }
101
123
  node.producerRecomputeValue(node);
102
124
  // After recomputing the value, we're no longer dirty.
103
125
  node.dirty = false;
126
+ node.lastCleanEpoch = epoch;
104
127
  }
105
128
  /**
106
129
  * Propagate a dirty notification to live consumers of this producer.
@@ -5,10 +5,10 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { SIGNAL } from '../symbol.js';
9
- import { Signal } from './api.js';
8
+ import type { Signal } from './api.js';
10
9
  import type { ValueEqualityFn } from './equality.js';
11
10
  import type { ReactiveNode } from './graph.js';
11
+ import { SIGNAL } from './graph.js';
12
12
  export interface SignalNode<T> extends ReactiveNode {
13
13
  value: T;
14
14
  equal: ValueEqualityFn<T>;
@@ -29,13 +29,16 @@ export declare function signalGetFn<T>(this: SignalNode<T>): T;
29
29
  export declare function signalSetFn<T>(node: SignalNode<T>, newValue: T): void;
30
30
  export declare function signalUpdateFn<T>(node: SignalNode<T>, updater: (value: T) => T): void;
31
31
  export declare function signalMutateFn<T>(node: SignalNode<T>, mutator: (value: T) => void): void;
32
+ /**
33
+ * A `Signal` with a value that can be mutated via a setter interface.
34
+ */
32
35
  export interface WritableSignal<T> extends Signal<T> {
33
36
  /**
34
37
  * Directly set the signal to a new value, and notify any dependents.
35
38
  */
36
39
  set(value: T): void;
37
40
  /**
38
- * Update the value of the signal based on itfs current value, and
41
+ * Update the value of the signal based on its current value, and
39
42
  * notify any dependents.
40
43
  */
41
44
  update(updateFn: (value: T) => T): void;
@@ -1,15 +1,7 @@
1
1
  /* eslint-disable */
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.io/license
8
- */
9
- import { SIGNAL } from '../symbol.js';
10
2
  import { defaultEquals } from './equality.js';
11
3
  import { throwInvalidWriteToSignalError } from './errors.js';
12
- import { producerAccessed, producerNotifyConsumers, producerUpdatesAllowed, REACTIVE_NODE } from './graph.js';
4
+ import { producerAccessed, producerIncrementEpoch, producerNotifyConsumers, producerUpdatesAllowed, REACTIVE_NODE, SIGNAL } from './graph.js';
13
5
  /**
14
6
  * If set, called after `WritableSignal`s are updated.
15
7
  *
@@ -43,7 +35,13 @@ export function signalSetFn(node, newValue) {
43
35
  if (!producerUpdatesAllowed()) {
44
36
  throwInvalidWriteToSignalError();
45
37
  }
46
- if (!node.equal(node.value, newValue)) {
38
+ const value = node.value;
39
+ if (Object.is(value, newValue)) {
40
+ if (!node.equal(value, newValue)) {
41
+ console.warn('Signal value equality implementations should always return `true` for values that are the same according to `Object.is` but returned `false` instead.');
42
+ }
43
+ }
44
+ else if (!node.equal(value, newValue)) {
47
45
  node.value = newValue;
48
46
  signalValueChanged(node);
49
47
  }
@@ -62,18 +60,14 @@ export function signalMutateFn(node, mutator) {
62
60
  mutator(node.value);
63
61
  signalValueChanged(node);
64
62
  }
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
- // TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
68
- const SIGNAL_NODE = /* @__PURE__ */ (() => {
69
- return {
70
- ...REACTIVE_NODE,
71
- equal: defaultEquals,
72
- value: undefined,
73
- };
74
- })();
63
+ const SIGNAL_NODE = {
64
+ ...REACTIVE_NODE,
65
+ equal: defaultEquals,
66
+ value: undefined,
67
+ };
75
68
  function signalValueChanged(node) {
76
69
  node.version++;
70
+ producerIncrementEpoch();
77
71
  producerNotifyConsumers(node);
78
72
  postSignalSetFn?.();
79
73
  }
@@ -1,5 +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.io/license
7
+ */
1
8
  import type { Observable, Subscribable } from 'rxjs';
2
- import { Signal } from './api.js';
9
+ import type { Signal } from './api.js';
3
10
  /**
4
11
  * Options for `toSignal`.
5
12
  */
@@ -19,6 +26,15 @@ export interface ToSignalOptions {
19
26
  * not met.
20
27
  */
21
28
  requireSync?: boolean;
29
+ /**
30
+ * Whether `toSignal` should throw errors from the Observable error channel back to RxJS, where
31
+ * they'll be processed as uncaught exceptions.
32
+ *
33
+ * In practice, this means that the signal returned by `toSignal` will keep returning the last
34
+ * good value forever, as Observables which error produce no further values. This option emulates
35
+ * the behavior of the `async` pipe.
36
+ */
37
+ rejectErrors?: boolean;
22
38
  }
23
39
  export declare function toSignal<T>(source: Observable<T> | Subscribable<T>): Signal<T | undefined>;
24
40
  export declare function toSignal<T>(source: Observable<T> | Subscribable<T>, options: ToSignalOptions & {
@@ -1,11 +1,4 @@
1
1
  /* eslint-disable */
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.io/license
8
- */
9
2
  import { registerFinalization } from '../../memory/finalization.js';
10
3
  import { assertNotInReactiveContext } from './asserts.js';
11
4
  import { computed } from './computed.js';
@@ -23,7 +16,8 @@ import { signal } from './signal.js';
23
16
  * does not include an `undefined` type.
24
17
  */
25
18
  export function toSignal(source, options) {
26
- assertNotInReactiveContext(toSignal, 'Invoking `toSignal` causes new subscriptions every time. Consider moving `toSignal` outside of the reactive context and read the signal value where needed.');
19
+ assertNotInReactiveContext(toSignal, 'Invoking `toSignal` causes new subscriptions every time. ' +
20
+ 'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.');
27
21
  // Note: T is the Observable value type, and U is the initial value type. They don't have to be
28
22
  // the same - the returned signal gives values of type `T`.
29
23
  let state;
@@ -43,7 +37,14 @@ export function toSignal(source, options) {
43
37
  // https://github.com/angular/angular/pull/50522.
44
38
  const sub = source.subscribe({
45
39
  next: value => state.set({ kind: StateKind.Value, value }),
46
- error: error => state.set({ kind: StateKind.Error, error }),
40
+ error: error => {
41
+ if (options?.rejectErrors) {
42
+ // Kick the error back to RxJS. It will be caught and rethrown in a macrotask, which causes
43
+ // the error to end up as an uncaught exception.
44
+ throw error;
45
+ }
46
+ state.set({ kind: StateKind.Error, error });
47
+ },
47
48
  // Completion of the Observable is meaningless to the signal. Signals don't have a concept of
48
49
  // "complete".
49
50
  });
@@ -60,6 +61,8 @@ export function toSignal(source, options) {
60
61
  case StateKind.Error:
61
62
  throw current.error;
62
63
  case StateKind.NoValue:
64
+ // This shouldn't really happen because the error is thrown on creation.
65
+ // TODO(alxhub): use a RuntimeError when we finalize the error semantics
63
66
  throw new Error('`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');
64
67
  }
65
68
  });
@@ -5,8 +5,8 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { SIGNAL } from '../symbol.js';
9
8
  import type { ReactiveNode } from './graph.js';
9
+ import { SIGNAL } from './graph.js';
10
10
  /**
11
11
  * A cleanup function that can be optionally registered from the watch logic. If registered, the
12
12
  * cleanup logic runs before the next watch execution.
@@ -1,13 +1,5 @@
1
1
  /* eslint-disable */
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.io/license
8
- */
9
- import { SIGNAL } from '../symbol.js';
10
- import { consumerAfterComputation, consumerBeforeComputation, consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, isInNotificationPhase, REACTIVE_NODE } from './graph.js';
2
+ import { consumerAfterComputation, consumerBeforeComputation, consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, isInNotificationPhase, REACTIVE_NODE, SIGNAL } from './graph.js';
11
3
  export function createWatch(fn, schedule, allowSignalWrites) {
12
4
  const node = Object.create(WATCH_NODE);
13
5
  if (allowSignalWrites) {
@@ -5,6 +5,5 @@ export * from './effect-with-dependencies.js';
5
5
  export * from './pipe.js';
6
6
  export * from './switch-map.js';
7
7
  export * from './to-lazy-signal.js';
8
- export * from './to-observable-2.js';
9
8
  export * from './types.js';
10
9
  export * from './untracked-operator.js';
package/signals/index.js CHANGED
@@ -5,6 +5,5 @@ export * from './effect-with-dependencies.js';
5
5
  export * from './pipe.js';
6
6
  export * from './switch-map.js';
7
7
  export * from './to-lazy-signal.js';
8
- export * from './to-observable-2.js';
9
8
  export * from './types.js';
10
9
  export * from './untracked-operator.js';
@@ -1,5 +1,5 @@
1
1
  import { computed } from './api.js';
2
2
  export function switchMap(source) {
3
- const outerSource = computed(() => source());
3
+ const outerSource = computed(source);
4
4
  return computed(() => outerSource()());
5
5
  }
package/signals/symbol.js CHANGED
@@ -3,4 +3,4 @@
3
3
  *
4
4
  * This can be used to auto-unwrap signals in various cases, or to auto-wrap non-signal values.
5
5
  */
6
- export const SIGNAL = /* @__PURE__ */ Symbol('SIGNAL');
6
+ export const SIGNAL = Symbol('SIGNAL');
@@ -1,23 +1 @@
1
- import type { Observable } from 'rxjs';
2
- import type { Signal, ToSignalOptions } from './api.js';
3
- /**
4
- * Like `toSignal`, except that it uses untracked internal operations (required for some scenarios, but might be less safe in terms of bugs catching) and has the ability to subscribe lazily.
5
- * Subscription to observable is cleaned up using finalization (garbage collection) of the signal.
6
- */
7
- export declare function toLazySignal<T>(source: Observable<T>): Signal<T | undefined>;
8
- export declare function toLazySignal<T>(source: Observable<T>, options: ToSignalOptions & {
9
- initialValue?: undefined;
10
- requireSync?: false;
11
- }): Signal<T | undefined>;
12
- export declare function toLazySignal<T>(source: Observable<T>, options: ToSignalOptions & {
13
- initialValue?: null;
14
- requireSync?: false;
15
- }): Signal<T | null>;
16
- export declare function toLazySignal<T>(source: Observable<T>, options: ToSignalOptions & {
17
- initialValue?: undefined;
18
- requireSync: true;
19
- }): Signal<T>;
20
- export declare function toLazySignal<T, const I>(source: Observable<T>, options: ToSignalOptions & {
21
- initialValue: I;
22
- requireSync?: false;
23
- }): Signal<T | I>;
1
+ export declare const toLazySignal: typeof import("./implementation/to-signal.js").toSignal;
@@ -1,20 +1,19 @@
1
1
  import { Subject, switchMap } from 'rxjs';
2
2
  import { computed, toSignal } from './api.js';
3
3
  const LAZY = Symbol('LAZY');
4
- export function toLazySignal(source, options) {
4
+ export const toLazySignal = function toLazySignal(source, options) {
5
5
  const subscribe$ = new Subject();
6
6
  const lazySource = subscribe$.pipe(switchMap(() => source));
7
7
  const signal = toSignal(lazySource, { initialValue: LAZY, ...options }); // eslint-disable-line @typescript-eslint/no-unsafe-argument
8
- let subscribed = false;
9
- return computed(() => {
10
- if (!subscribed) {
11
- subscribed = true;
12
- subscribe$.next();
13
- subscribe$.complete();
14
- if (signal() == LAZY) {
15
- throw new Error('`toLazySignal()` called with `requireSync` but `Observable` did not emit synchronously.');
16
- }
8
+ let computation = () => {
9
+ subscribe$.next();
10
+ subscribe$.complete();
11
+ const value = signal();
12
+ computation = signal;
13
+ if (value == LAZY) {
14
+ throw new Error('`toLazySignal()` called with `requireSync` but `Observable` did not emit synchronously.');
17
15
  }
18
- return signal();
19
- });
20
- }
16
+ return value;
17
+ };
18
+ return computed(() => computation());
19
+ };
@@ -1,8 +0,0 @@
1
- import type { Observable } from 'rxjs';
2
- import type { Signal } from './api.js';
3
- /**
4
- * Exposes the value of an `Signal` as an RxJS `Observable`.
5
- *
6
- * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`.
7
- */
8
- export declare function toObservable2<T>(source: Signal<T>): Observable<T>;
@@ -1,9 +0,0 @@
1
- import { toObservable } from './implementation/to-observable.js';
2
- /**
3
- * Exposes the value of an `Signal` as an RxJS `Observable`.
4
- *
5
- * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`.
6
- */
7
- export function toObservable2(source) {
8
- return toObservable(source);
9
- }