@signaldb/core 1.4.0 → 1.5.1

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.
@@ -44,6 +44,7 @@ interface CollectionEvents<T extends BaseItem, U = T> {
44
44
  'replaceOne': (selector: Selector<T>, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
45
45
  'removeOne': (selector: Selector<T>) => void;
46
46
  'removeMany': (selector: Selector<T>) => void;
47
+ 'validate': (item: T) => void;
47
48
  '_debug.getItems': (callstack: string, selector: Selector<T> | undefined, measuredTime: number) => void;
48
49
  '_debug.find': <O extends FindOptions<T>>(callstack: string, selector: Selector<T> | undefined, options: O | undefined, cursor: Cursor<T, U>) => void;
49
50
  '_debug.findOne': <O extends FindOptions<T>>(callstack: string, selector: Selector<T>, options: O | undefined, item: U | undefined) => void;
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
- function createSignal(dependency, initialValue, isEqual = Object.is) {
2
+ function createSignal(reactivityAdapter, initialValue, isEqual = Object.is) {
3
3
  let value = initialValue;
4
+ const dependency = reactivityAdapter == null ? void 0 : reactivityAdapter.create();
5
+ const isInReactiveScope = () => {
6
+ if (!(reactivityAdapter == null ? void 0 : reactivityAdapter.isInScope))
7
+ return true;
8
+ return reactivityAdapter.isInScope();
9
+ };
4
10
  const signal = {
5
11
  get() {
6
- if (dependency)
12
+ if (dependency && isInReactiveScope())
7
13
  dependency.depend();
8
14
  return value;
9
15
  },
@@ -54,7 +54,6 @@ const _Collection = class _Collection extends EventEmitter {
54
54
  * @param options.fieldTracking - A boolean to enable or disable field tracking by default.
55
55
  */
56
56
  constructor(options) {
57
- var _a, _b;
58
57
  super();
59
58
  __publicField(this, "name");
60
59
  __publicField(this, "options");
@@ -83,8 +82,8 @@ const _Collection = class _Collection extends EventEmitter {
83
82
  ...this.options.indices || []
84
83
  ];
85
84
  this.rebuildIndices();
86
- this.isPullingSignal = createSignal((_a = this.options.reactivity) == null ? void 0 : _a.create(), !!(options == null ? void 0 : options.persistence));
87
- this.isPushingSignal = createSignal((_b = this.options.reactivity) == null ? void 0 : _b.create(), false);
85
+ this.isPullingSignal = createSignal(this.options.reactivity, !!(options == null ? void 0 : options.persistence));
86
+ this.isPushingSignal = createSignal(this.options.reactivity, false);
88
87
  this.on("persistence.pullStarted", () => {
89
88
  this.isPullingSignal.set(true);
90
89
  });
@@ -530,6 +529,7 @@ const _Collection = class _Collection extends EventEmitter {
530
529
  if (!item)
531
530
  throw new Error("Invalid item");
532
531
  const newItem = { id: randomId(), ...item };
532
+ this.emit("validate", newItem);
533
533
  if (this.idIndex.has(serializeValue(newItem.id)))
534
534
  throw new Error("Item with same id already exists");
535
535
  this.memory().push(newItem);
@@ -600,6 +600,7 @@ const _Collection = class _Collection extends EventEmitter {
600
600
  if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
601
601
  throw new Error("Item with same id already exists");
602
602
  }
603
+ this.emit("validate", modifiedItem);
603
604
  this.memory().splice(index, 1, modifiedItem);
604
605
  this.rebuildIndices();
605
606
  this.emit("changed", modifiedItem, restModifier);
@@ -649,6 +650,7 @@ const _Collection = class _Collection extends EventEmitter {
649
650
  if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
650
651
  throw new Error(`Item with same id '${modifiedItem.id}' already exists`);
651
652
  }
653
+ this.emit("validate", modifiedItem);
652
654
  return {
653
655
  item: modifiedItem,
654
656
  index
@@ -692,6 +694,7 @@ const _Collection = class _Collection extends EventEmitter {
692
694
  throw new Error("Item with same id already exists");
693
695
  }
694
696
  const modifiedItem = { id: item.id, ...replacement };
697
+ this.emit("validate", modifiedItem);
695
698
  this.memory().splice(index, 1, modifiedItem);
696
699
  this.rebuildIndices();
697
700
  this.emit("changed", modifiedItem, replacement);
@@ -38,7 +38,6 @@ class ReplicatedCollection extends index.default {
38
38
  * @param options.enableDebugMode - A boolean to enable or disable debug mode.
39
39
  */
40
40
  constructor(options) {
41
- var _a, _b;
42
41
  const replicationAdapter = createReplicationAdapter({
43
42
  registerRemoteChange: options.registerRemoteChange,
44
43
  pull: async () => {
@@ -67,8 +66,8 @@ class ReplicatedCollection extends index.default {
67
66
  });
68
67
  __publicField(this, "isPullingRemoteSignal");
69
68
  __publicField(this, "isPushingRemoteSignal");
70
- this.isPullingRemoteSignal = createSignal((_a = options.reactivity) == null ? void 0 : _a.create(), false);
71
- this.isPushingRemoteSignal = createSignal((_b = options.reactivity) == null ? void 0 : _b.create(), false);
69
+ this.isPullingRemoteSignal = createSignal(options.reactivity, false);
70
+ this.isPushingRemoteSignal = createSignal(options.reactivity, false);
72
71
  }
73
72
  /**
74
73
  * Checks whether the collection is currently performing any loading operation,
@@ -11,7 +11,6 @@ class AutoFetchCollection extends ReplicatedCollection.default {
11
11
  * @param options.purgeDelay {Number} - The delay in milliseconds before purging an item from the cache.
12
12
  */
13
13
  constructor(options) {
14
- var _a;
15
14
  let triggerRemoteChange;
16
15
  super({
17
16
  ...options,
@@ -46,7 +45,7 @@ class AutoFetchCollection extends ReplicatedCollection.default {
46
45
  __publicField(this, "mergeItems");
47
46
  this.mergeItems = options.mergeItems ?? ((itemA, itemB) => ({ ...itemA, ...itemB }));
48
47
  this.purgeDelay = options.purgeDelay ?? 1e4;
49
- this.isFetchingSignal = createSignal((_a = options.reactivity) == null ? void 0 : _a.create(), false);
48
+ this.isFetchingSignal = createSignal(options.reactivity, false);
50
49
  if (!triggerRemoteChange)
51
50
  throw new Error("No triggerRemoteChange method found. Looks like your persistence adapter was not registered");
52
51
  this.triggerReload = triggerRemoteChange;
@@ -147,7 +146,7 @@ class AutoFetchCollection extends ReplicatedCollection.default {
147
146
  if (!this.reactivityAdapter)
148
147
  throw new Error("No reactivity adapter found");
149
148
  if (!this.loadingSignals.has(this.getKeyForSelector(selector))) {
150
- this.loadingSignals.set(this.getKeyForSelector(selector), createSignal(this.reactivityAdapter.create(), false));
149
+ this.loadingSignals.set(this.getKeyForSelector(selector), createSignal(this.reactivityAdapter, false));
151
150
  }
152
151
  return this.loadingSignals.get(this.getKeyForSelector(selector));
153
152
  }
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export type { default as MemoryAdapter } from './types/MemoryAdapter';
3
3
  export type { default as PersistenceAdapter, Changeset, LoadResponse, } from './types/PersistenceAdapter';
4
4
  export type { default as Selector } from './types/Selector';
5
5
  export type { default as Modifier } from './types/Modifier';
6
- export type { BaseItem, ObserveCallbacks, CursorOptions, Transform, SortSpecifier, FieldSpecifier, FindOptions, } from './Collection';
6
+ export type { BaseItem, ObserveCallbacks, CursorOptions, Transform, SortSpecifier, FieldSpecifier, FindOptions, CollectionOptions, } from './Collection';
7
7
  export { default as Collection, createIndex } from './Collection';
8
8
  export { default as AutoFetchCollection } from './AutoFetchCollection';
9
9
  export { default as combinePersistenceAdapters } from './persistence/combinePersistenceAdapters';
package/dist/index17.mjs CHANGED
@@ -1,8 +1,14 @@
1
- function createSignal(dependency, initialValue, isEqual = Object.is) {
1
+ function createSignal(reactivityAdapter, initialValue, isEqual = Object.is) {
2
2
  let value = initialValue;
3
+ const dependency = reactivityAdapter == null ? void 0 : reactivityAdapter.create();
4
+ const isInReactiveScope = () => {
5
+ if (!(reactivityAdapter == null ? void 0 : reactivityAdapter.isInScope))
6
+ return true;
7
+ return reactivityAdapter.isInScope();
8
+ };
3
9
  const signal = {
4
10
  get() {
5
- if (dependency)
11
+ if (dependency && isInReactiveScope())
6
12
  dependency.depend();
7
13
  return value;
8
14
  },
package/dist/index2.mjs CHANGED
@@ -53,7 +53,6 @@ const _Collection = class _Collection extends EventEmitter {
53
53
  * @param options.fieldTracking - A boolean to enable or disable field tracking by default.
54
54
  */
55
55
  constructor(options) {
56
- var _a, _b;
57
56
  super();
58
57
  __publicField(this, "name");
59
58
  __publicField(this, "options");
@@ -82,8 +81,8 @@ const _Collection = class _Collection extends EventEmitter {
82
81
  ...this.options.indices || []
83
82
  ];
84
83
  this.rebuildIndices();
85
- this.isPullingSignal = createSignal((_a = this.options.reactivity) == null ? void 0 : _a.create(), !!(options == null ? void 0 : options.persistence));
86
- this.isPushingSignal = createSignal((_b = this.options.reactivity) == null ? void 0 : _b.create(), false);
84
+ this.isPullingSignal = createSignal(this.options.reactivity, !!(options == null ? void 0 : options.persistence));
85
+ this.isPushingSignal = createSignal(this.options.reactivity, false);
87
86
  this.on("persistence.pullStarted", () => {
88
87
  this.isPullingSignal.set(true);
89
88
  });
@@ -529,6 +528,7 @@ const _Collection = class _Collection extends EventEmitter {
529
528
  if (!item)
530
529
  throw new Error("Invalid item");
531
530
  const newItem = { id: randomId(), ...item };
531
+ this.emit("validate", newItem);
532
532
  if (this.idIndex.has(serializeValue(newItem.id)))
533
533
  throw new Error("Item with same id already exists");
534
534
  this.memory().push(newItem);
@@ -599,6 +599,7 @@ const _Collection = class _Collection extends EventEmitter {
599
599
  if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
600
600
  throw new Error("Item with same id already exists");
601
601
  }
602
+ this.emit("validate", modifiedItem);
602
603
  this.memory().splice(index, 1, modifiedItem);
603
604
  this.rebuildIndices();
604
605
  this.emit("changed", modifiedItem, restModifier);
@@ -648,6 +649,7 @@ const _Collection = class _Collection extends EventEmitter {
648
649
  if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
649
650
  throw new Error(`Item with same id '${modifiedItem.id}' already exists`);
650
651
  }
652
+ this.emit("validate", modifiedItem);
651
653
  return {
652
654
  item: modifiedItem,
653
655
  index
@@ -691,6 +693,7 @@ const _Collection = class _Collection extends EventEmitter {
691
693
  throw new Error("Item with same id already exists");
692
694
  }
693
695
  const modifiedItem = { id: item.id, ...replacement };
696
+ this.emit("validate", modifiedItem);
694
697
  this.memory().splice(index, 1, modifiedItem);
695
698
  this.rebuildIndices();
696
699
  this.emit("changed", modifiedItem, replacement);
package/dist/index20.mjs CHANGED
@@ -36,7 +36,6 @@ class ReplicatedCollection extends Collection {
36
36
  * @param options.enableDebugMode - A boolean to enable or disable debug mode.
37
37
  */
38
38
  constructor(options) {
39
- var _a, _b;
40
39
  const replicationAdapter = createReplicationAdapter({
41
40
  registerRemoteChange: options.registerRemoteChange,
42
41
  pull: async () => {
@@ -65,8 +64,8 @@ class ReplicatedCollection extends Collection {
65
64
  });
66
65
  __publicField(this, "isPullingRemoteSignal");
67
66
  __publicField(this, "isPushingRemoteSignal");
68
- this.isPullingRemoteSignal = createSignal((_a = options.reactivity) == null ? void 0 : _a.create(), false);
69
- this.isPushingRemoteSignal = createSignal((_b = options.reactivity) == null ? void 0 : _b.create(), false);
67
+ this.isPullingRemoteSignal = createSignal(options.reactivity, false);
68
+ this.isPushingRemoteSignal = createSignal(options.reactivity, false);
70
69
  }
71
70
  /**
72
71
  * Checks whether the collection is currently performing any loading operation,
package/dist/index3.mjs CHANGED
@@ -10,7 +10,6 @@ class AutoFetchCollection extends ReplicatedCollection {
10
10
  * @param options.purgeDelay {Number} - The delay in milliseconds before purging an item from the cache.
11
11
  */
12
12
  constructor(options) {
13
- var _a;
14
13
  let triggerRemoteChange;
15
14
  super({
16
15
  ...options,
@@ -45,7 +44,7 @@ class AutoFetchCollection extends ReplicatedCollection {
45
44
  __publicField(this, "mergeItems");
46
45
  this.mergeItems = options.mergeItems ?? ((itemA, itemB) => ({ ...itemA, ...itemB }));
47
46
  this.purgeDelay = options.purgeDelay ?? 1e4;
48
- this.isFetchingSignal = createSignal((_a = options.reactivity) == null ? void 0 : _a.create(), false);
47
+ this.isFetchingSignal = createSignal(options.reactivity, false);
49
48
  if (!triggerRemoteChange)
50
49
  throw new Error("No triggerRemoteChange method found. Looks like your persistence adapter was not registered");
51
50
  this.triggerReload = triggerRemoteChange;
@@ -146,7 +145,7 @@ class AutoFetchCollection extends ReplicatedCollection {
146
145
  if (!this.reactivityAdapter)
147
146
  throw new Error("No reactivity adapter found");
148
147
  if (!this.loadingSignals.has(this.getKeyForSelector(selector))) {
149
- this.loadingSignals.set(this.getKeyForSelector(selector), createSignal(this.reactivityAdapter.create(), false));
148
+ this.loadingSignals.set(this.getKeyForSelector(selector), createSignal(this.reactivityAdapter, false));
150
149
  }
151
150
  return this.loadingSignals.get(this.getKeyForSelector(selector));
152
151
  }
@@ -1,14 +1,14 @@
1
- import type Dependency from '../types/Dependency';
1
+ import type ReactivityAdapter from '../types/ReactivityAdapter';
2
2
  import type Signal from '../types/Signal';
3
3
  /**
4
4
  * Creates a reactive signal for managing state and triggering dependencies.
5
5
  * The signal holds a value and provides methods to get and set the value,
6
6
  * with optional equality checks and dependency tracking.
7
7
  * @template T - The type of the value held by the signal.
8
- * @param dependency - An optional dependency object for tracking and notifying reactivity.
8
+ * @param reactivityAdapter - An optional reactivity adapter for managing dependencies.
9
9
  * @param initialValue - The initial value of the signal.
10
10
  * @param isEqual - A custom equality function to determine if the new value is different
11
11
  * from the current value (default is `Object.is`).
12
12
  * @returns A signal object with `get` and `set` methods to manage the value.
13
13
  */
14
- export default function createSignal<T>(dependency: Dependency | undefined, initialValue: T, isEqual?: (a: T, b: T) => boolean): Signal<T>;
14
+ export default function createSignal<T>(reactivityAdapter: ReactivityAdapter | undefined, initialValue: T, isEqual?: (a: T, b: T) => boolean): Signal<T>;
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@signaldb/core",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "description": "SignalDB is a client-side database that provides a simple MongoDB-like interface to the data with first-class typescript support to achieve an optimistic UI. Data persistence can be achieved by using storage providers that store the data through a JSON interface to places such as localStorage.",
5
5
  "scripts": {
6
- "build": "rimraf dist && vite build"
6
+ "build": "rimraf dist && vite build",
7
+ "test": "vitest"
7
8
  },
8
9
  "repository": {
9
10
  "type": "git",
@@ -54,5 +55,8 @@
54
55
  "dependencies": {
55
56
  "fast-sort": "^3.4.1",
56
57
  "mingo": "^6.5.1"
58
+ },
59
+ "devDependencies": {
60
+ "zod": "^3.24.2"
57
61
  }
58
62
  }