@super-line/store-memory 0.5.0 → 0.6.0

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/dist/index.cjs CHANGED
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  module.exports = __toCommonJS(index_exports);
27
27
  var import_core = require("@super-line/core");
28
28
  var randomId = () => Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
29
+ var SERVER_ORIGIN = "server";
29
30
  function memoryStoreServer() {
30
31
  const resources = /* @__PURE__ */ new Map();
31
32
  const listeners = /* @__PURE__ */ new Set();
@@ -34,6 +35,10 @@ function memoryStoreServer() {
34
35
  if (!r) throw new import_core.SuperLineError("NOT_FOUND", `No resource: ${id}`);
35
36
  return r;
36
37
  };
38
+ const commit = (change) => {
39
+ get(change.id).data = change.update;
40
+ for (const cb of listeners) cb(change);
41
+ };
37
42
  return {
38
43
  clustering: "relay",
39
44
  read(id) {
@@ -44,9 +49,41 @@ function memoryStoreServer() {
44
49
  resources.set(id, { id, accessRules, data });
45
50
  },
46
51
  apply(change) {
47
- const r = get(change.id);
48
- r.data = change.update;
49
- for (const cb of listeners) cb(change);
52
+ commit(change);
53
+ },
54
+ open(id, openOpts) {
55
+ get(id);
56
+ const origin = openOpts?.origin ?? SERVER_ORIGIN;
57
+ const subs = /* @__PURE__ */ new Set();
58
+ const snap = () => resources.get(id)?.data;
59
+ return {
60
+ getSnapshot: snap,
61
+ subscribe: (cb) => {
62
+ const wrap = (c) => {
63
+ if (c.id === id) cb();
64
+ };
65
+ listeners.add(wrap);
66
+ const off = () => void listeners.delete(wrap);
67
+ subs.add(off);
68
+ return () => {
69
+ off();
70
+ subs.delete(off);
71
+ };
72
+ },
73
+ // LWW: every write replaces the whole value. delete/update must build a NEW value (read returns the
74
+ // LIVE object + commit swaps by reference), so the prior snapshot is never mutated in place.
75
+ set: (data) => commit({ id, update: data, origin }),
76
+ update: (partial) => {
77
+ const cur = snap();
78
+ const base = typeof cur === "object" && cur !== null ? cur : {};
79
+ commit({ id, update: { ...base, ...partial }, origin });
80
+ },
81
+ delete: (path) => commit({ id, update: (0, import_core.removeAtPath)(snap(), path), origin }),
82
+ close: () => {
83
+ for (const off of subs) off();
84
+ subs.clear();
85
+ }
86
+ };
50
87
  },
51
88
  setAccess(id, accessRules) {
52
89
  get(id).accessRules = accessRules;
@@ -96,6 +133,11 @@ var LwwReplica = class {
96
133
  const base = typeof this.value === "object" && this.value !== null ? this.value : {};
97
134
  return this.set({ ...base, ...partial });
98
135
  }
136
+ // Drop the value at `path` and replace (LWW). `removeAtPath` returns a fresh value, so `set`'s identity
137
+ // guard sees a change and the prior snapshot is never mutated in place.
138
+ delete(path) {
139
+ return this.set((0, import_core.removeAtPath)(this.value, path));
140
+ }
99
141
  applyRemote(change) {
100
142
  if (change.origin === this.origin) return;
101
143
  this.value = change.update;
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // src/index.ts
2
- import { SuperLineError } from "@super-line/core";
2
+ import { SuperLineError, removeAtPath } from "@super-line/core";
3
3
  var randomId = () => Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
4
+ var SERVER_ORIGIN = "server";
4
5
  function memoryStoreServer() {
5
6
  const resources = /* @__PURE__ */ new Map();
6
7
  const listeners = /* @__PURE__ */ new Set();
@@ -9,6 +10,10 @@ function memoryStoreServer() {
9
10
  if (!r) throw new SuperLineError("NOT_FOUND", `No resource: ${id}`);
10
11
  return r;
11
12
  };
13
+ const commit = (change) => {
14
+ get(change.id).data = change.update;
15
+ for (const cb of listeners) cb(change);
16
+ };
12
17
  return {
13
18
  clustering: "relay",
14
19
  read(id) {
@@ -19,9 +24,41 @@ function memoryStoreServer() {
19
24
  resources.set(id, { id, accessRules, data });
20
25
  },
21
26
  apply(change) {
22
- const r = get(change.id);
23
- r.data = change.update;
24
- for (const cb of listeners) cb(change);
27
+ commit(change);
28
+ },
29
+ open(id, openOpts) {
30
+ get(id);
31
+ const origin = openOpts?.origin ?? SERVER_ORIGIN;
32
+ const subs = /* @__PURE__ */ new Set();
33
+ const snap = () => resources.get(id)?.data;
34
+ return {
35
+ getSnapshot: snap,
36
+ subscribe: (cb) => {
37
+ const wrap = (c) => {
38
+ if (c.id === id) cb();
39
+ };
40
+ listeners.add(wrap);
41
+ const off = () => void listeners.delete(wrap);
42
+ subs.add(off);
43
+ return () => {
44
+ off();
45
+ subs.delete(off);
46
+ };
47
+ },
48
+ // LWW: every write replaces the whole value. delete/update must build a NEW value (read returns the
49
+ // LIVE object + commit swaps by reference), so the prior snapshot is never mutated in place.
50
+ set: (data) => commit({ id, update: data, origin }),
51
+ update: (partial) => {
52
+ const cur = snap();
53
+ const base = typeof cur === "object" && cur !== null ? cur : {};
54
+ commit({ id, update: { ...base, ...partial }, origin });
55
+ },
56
+ delete: (path) => commit({ id, update: removeAtPath(snap(), path), origin }),
57
+ close: () => {
58
+ for (const off of subs) off();
59
+ subs.clear();
60
+ }
61
+ };
25
62
  },
26
63
  setAccess(id, accessRules) {
27
64
  get(id).accessRules = accessRules;
@@ -71,6 +108,11 @@ var LwwReplica = class {
71
108
  const base = typeof this.value === "object" && this.value !== null ? this.value : {};
72
109
  return this.set({ ...base, ...partial });
73
110
  }
111
+ // Drop the value at `path` and replace (LWW). `removeAtPath` returns a fresh value, so `set`'s identity
112
+ // guard sees a change and the prior snapshot is never mutated in place.
113
+ delete(path) {
114
+ return this.set(removeAtPath(this.value, path));
115
+ }
74
116
  applyRemote(change) {
75
117
  if (change.origin === this.origin) return;
76
118
  this.value = change.update;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@super-line/store-memory",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "In-memory last-writer-wins Store for super-line — the zero-dependency default Store pair.",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  "access": "public"
46
46
  },
47
47
  "dependencies": {
48
- "@super-line/core": "^0.5.0"
48
+ "@super-line/core": "^0.6.0"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "tsup"