@tstdl/base 0.88.5 → 0.88.7

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,6 +1,6 @@
1
1
  import { NotFoundError } from '../../error/not-found.error.js';
2
2
  import { objectKeys } from '../../utils/object/object.js';
3
- import { assertDefined, isNullOrUndefined } from '../../utils/type-guards.js';
3
+ import { assertDefined, isNull, isNullOrUndefined } from '../../utils/type-guards.js';
4
4
  import { mongoDocumentFromMaybeNewEntity, toEntity, toMongoDocument, toMongoProjection, toNewEntity, toProjectedEntity } from './model/document.js';
5
5
  import { MongoBulk } from './mongo-bulk.js';
6
6
  import { replaceOneOperation, updateOneOperation } from './operations.js';
@@ -116,18 +116,18 @@ export class MongoBaseRepository {
116
116
  }
117
117
  async tryLoadByFilterAndDelete(filter, options) {
118
118
  const result = await this.collection.findOneAndDelete(filter, options);
119
- if (result.value == undefined) {
119
+ if (isNull(result)) {
120
120
  return undefined;
121
121
  }
122
- return toEntity(result.value);
122
+ return toEntity(result);
123
123
  }
124
124
  async loadByFilterAndUpdate(filter, update, options) {
125
125
  const entity = await this.tryLoadByFilterAndUpdate(filter, update, options);
126
126
  return throwIfUndefinedElsePass(entity, this.collection.collectionName);
127
127
  }
128
128
  async tryLoadByFilterAndUpdate(filter, update, options) {
129
- const { value: document } = await this.collection.findOneAndUpdate(filter, update, options);
130
- if (document == undefined) {
129
+ const document = await this.collection.findOneAndUpdate(filter, update, options);
130
+ if (isNull(document)) {
131
131
  return undefined;
132
132
  }
133
133
  return toEntity(document);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.88.5",
3
+ "version": "0.88.7",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -120,7 +120,7 @@
120
120
  "./utils/string": "./utils/object/index.js"
121
121
  },
122
122
  "dependencies": {
123
- "disposablestack": "^1.1.1",
123
+ "disposablestack": "^1.1",
124
124
  "luxon": "^3.4",
125
125
  "reflect-metadata": "^0.1",
126
126
  "rxjs": "^7.8",
@@ -159,9 +159,9 @@
159
159
  "koa": "^2.14",
160
160
  "minio": "^7.1",
161
161
  "mjml": "^4.14",
162
- "mongodb": "^5.8",
162
+ "mongodb": "^6.1",
163
163
  "nodemailer": "^6.9",
164
- "playwright": "^1.37",
164
+ "playwright": "^1.38",
165
165
  "preact": "^10.17",
166
166
  "preact-render-to-string": "^6.2",
167
167
  "undici": "^5.24",
@@ -9,21 +9,8 @@ type Version = number & {
9
9
  __brand: 'Version';
10
10
  };
11
11
  export declare function setActiveConsumer(consumer: ReactiveNode | null): ReactiveNode | null;
12
- export declare const REACTIVE_NODE: {
13
- version: Version;
14
- dirty: boolean;
15
- producerNode: undefined;
16
- producerLastReadVersion: undefined;
17
- producerIndexOfThis: undefined;
18
- nextProducerIndex: number;
19
- liveConsumerNode: undefined;
20
- liveConsumerIndexOfThis: undefined;
21
- consumerAllowSignalWrites: boolean;
22
- consumerIsAlwaysLive: boolean;
23
- producerMustRecompute: () => boolean;
24
- producerRecomputeValue: () => void;
25
- consumerMarkedDirty: () => void;
26
- };
12
+ export declare function isInNotificationPhase(): boolean;
13
+ export declare const REACTIVE_NODE: ReactiveNode;
27
14
  /**
28
15
  * A producer and/or consumer which participates in the reactive graph.
29
16
  *
@@ -17,6 +17,9 @@ export function setActiveConsumer(consumer) {
17
17
  activeConsumer = consumer;
18
18
  return prev;
19
19
  }
20
+ export function isInNotificationPhase() {
21
+ return inNotificationPhase;
22
+ }
20
23
  export const REACTIVE_NODE = {
21
24
  version: 0,
22
25
  dirty: false,
@@ -153,7 +156,9 @@ export function consumerAfterComputation(node, prevConsumer) {
153
156
  }
154
157
  }
155
158
  // Truncate the producer tracking arrays.
156
- for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {
159
+ // Perf note: this is essentially truncating the length to `node.nextProducerIndex`, but
160
+ // benchmarking has shown that individual pop operations are faster.
161
+ while (node.producerNode.length > node.nextProducerIndex) {
157
162
  node.producerNode.pop();
158
163
  node.producerLastReadVersion.pop();
159
164
  node.producerIndexOfThis.pop();
@@ -1,7 +1,7 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import type { Signal } from './api.js';
3
3
  /**
4
- * Exposes the value of an Angular `Signal` as an RxJS `Observable`.
4
+ * Exposes the value of an `Signal` as an RxJS `Observable`.
5
5
  *
6
6
  * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`.
7
7
  */
@@ -2,7 +2,7 @@ import { Observable } from 'rxjs';
2
2
  import { effect } from './effect.js';
3
3
  import { untracked } from './untracked.js';
4
4
  /**
5
- * Exposes the value of an Angular `Signal` as an RxJS `Observable`.
5
+ * Exposes the value of an `Signal` as an RxJS `Observable`.
6
6
  *
7
7
  * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`.
8
8
  */
@@ -24,5 +24,11 @@ export interface Watch {
24
24
  */
25
25
  run(): void;
26
26
  cleanup(): void;
27
+ /**
28
+ * Destroy the watcher:
29
+ * - disconnect it from the reactive graph;
30
+ * - mark it as destroyed so subsequent run and notify operations are noop.
31
+ */
32
+ destroy(): void;
27
33
  }
28
34
  export declare function watch(fn: (onCleanup: WatchCleanupRegisterFn) => void, schedule: (watch: Watch) => void, allowSignalWrites: boolean): Watch;
@@ -5,7 +5,7 @@
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 { consumerAfterComputation, consumerBeforeComputation, consumerMarkDirty, consumerPollProducersForChange, REACTIVE_NODE } from './graph.js';
8
+ import { consumerAfterComputation, consumerBeforeComputation, consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, isInNotificationPhase, REACTIVE_NODE } from './graph.js';
9
9
  export function watch(fn, schedule, allowSignalWrites) {
10
10
  const node = Object.create(WATCH_NODE);
11
11
  if (allowSignalWrites) {
@@ -16,7 +16,27 @@ export function watch(fn, schedule, allowSignalWrites) {
16
16
  const registerOnCleanup = (cleanupFn) => {
17
17
  node.cleanupFn = cleanupFn;
18
18
  };
19
+ function isWatchNodeDestroyed(node) {
20
+ return node.fn === null && node.schedule === null;
21
+ }
22
+ function destroyWatchNode(node) {
23
+ if (!isWatchNodeDestroyed(node)) {
24
+ consumerDestroy(node); // disconnect watcher from the reactive graph
25
+ node.cleanupFn();
26
+ // nullify references to the integration functions to mark node as destroyed
27
+ node.fn = null;
28
+ node.schedule = null;
29
+ node.cleanupFn = NOOP_CLEANUP_FN;
30
+ }
31
+ }
19
32
  const run = () => {
33
+ if (node.fn === null) {
34
+ // trying to run a destroyed watch is noop
35
+ return;
36
+ }
37
+ if (isInNotificationPhase()) {
38
+ throw new Error(`Schedulers cannot synchronously execute watches while scheduling.`);
39
+ }
20
40
  node.dirty = false;
21
41
  if (node.hasRun && !consumerPollProducersForChange(node)) {
22
42
  return;
@@ -36,6 +56,7 @@ export function watch(fn, schedule, allowSignalWrites) {
36
56
  notify: () => consumerMarkDirty(node),
37
57
  run,
38
58
  cleanup: () => node.cleanupFn(),
59
+ destroy: () => destroyWatchNode(node),
39
60
  };
40
61
  return node.ref;
41
62
  }
@@ -45,7 +66,9 @@ const WATCH_NODE = {
45
66
  consumerIsAlwaysLive: true,
46
67
  consumerAllowSignalWrites: false,
47
68
  consumerMarkedDirty: (node) => {
48
- node.schedule(node.ref);
69
+ if (node.schedule !== null) {
70
+ node.schedule(node.ref);
71
+ }
49
72
  },
50
73
  hasRun: false,
51
74
  cleanupFn: NOOP_CLEANUP_FN,
@@ -4,6 +4,7 @@ export * from './effect-with-dependencies.js';
4
4
  export * from './lazylize.js';
5
5
  export * from './pipe.js';
6
6
  export * from './switch-map.js';
7
+ export * from './to-observable-2.js';
7
8
  export * from './to-signal-2.js';
8
9
  export * from './types.js';
9
10
  export * from './untracked-operator.js';
package/signals/index.js CHANGED
@@ -4,6 +4,7 @@ export * from './effect-with-dependencies.js';
4
4
  export * from './lazylize.js';
5
5
  export * from './pipe.js';
6
6
  export * from './switch-map.js';
7
+ export * from './to-observable-2.js';
7
8
  export * from './to-signal-2.js';
8
9
  export * from './types.js';
9
10
  export * from './untracked-operator.js';
@@ -0,0 +1,8 @@
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>;
@@ -0,0 +1,9 @@
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
+ }
@@ -5,7 +5,10 @@ export type ToSignal2Options<T> = ToSignalOptions<T> & {
5
5
  /** defer subscription until signal is used */
6
6
  lazy?: boolean;
7
7
  };
8
- /** 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 */
8
+ /**
9
+ * 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.
10
+ * Subscription to observable is cleaned up using finalization (garbage collection) of the signal.
11
+ */
9
12
  export declare function toSignal2<T>(source: ToSignalInput<T>): Signal<T | undefined>;
10
13
  export declare function toSignal2<T>(source: ToSignalInput<T>, options: ToSignal2Options<undefined> & {
11
14
  requireSync: true;