@super-line/store-memory 0.5.0 → 0.7.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,8 +35,13 @@ 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",
44
+ model: "lww",
39
45
  read(id) {
40
46
  return resources.get(id);
41
47
  },
@@ -44,9 +50,41 @@ function memoryStoreServer() {
44
50
  resources.set(id, { id, accessRules, data });
45
51
  },
46
52
  apply(change) {
47
- const r = get(change.id);
48
- r.data = change.update;
49
- for (const cb of listeners) cb(change);
53
+ commit(change);
54
+ },
55
+ open(id, openOpts) {
56
+ get(id);
57
+ const origin = openOpts?.origin ?? SERVER_ORIGIN;
58
+ const subs = /* @__PURE__ */ new Set();
59
+ const snap = () => resources.get(id)?.data;
60
+ return {
61
+ getSnapshot: snap,
62
+ subscribe: (cb) => {
63
+ const wrap = (c) => {
64
+ if (c.id === id) cb();
65
+ };
66
+ listeners.add(wrap);
67
+ const off = () => void listeners.delete(wrap);
68
+ subs.add(off);
69
+ return () => {
70
+ off();
71
+ subs.delete(off);
72
+ };
73
+ },
74
+ // LWW: every write replaces the whole value. delete/update must build a NEW value (read returns the
75
+ // LIVE object + commit swaps by reference), so the prior snapshot is never mutated in place.
76
+ set: (data) => commit({ id, update: data, origin }),
77
+ update: (partial) => {
78
+ const cur = snap();
79
+ const base = typeof cur === "object" && cur !== null ? cur : {};
80
+ commit({ id, update: { ...base, ...partial }, origin });
81
+ },
82
+ delete: (path) => commit({ id, update: (0, import_core.removeAtPath)(snap(), path), origin }),
83
+ close: () => {
84
+ for (const off of subs) off();
85
+ subs.clear();
86
+ }
87
+ };
50
88
  },
51
89
  setAccess(id, accessRules) {
52
90
  get(id).accessRules = accessRules;
@@ -96,6 +134,11 @@ var LwwReplica = class {
96
134
  const base = typeof this.value === "object" && this.value !== null ? this.value : {};
97
135
  return this.set({ ...base, ...partial });
98
136
  }
137
+ // Drop the value at `path` and replace (LWW). `removeAtPath` returns a fresh value, so `set`'s identity
138
+ // guard sees a change and the prior snapshot is never mutated in place.
139
+ delete(path) {
140
+ return this.set((0, import_core.removeAtPath)(this.value, path));
141
+ }
99
142
  applyRemote(change) {
100
143
  if (change.origin === this.origin) return;
101
144
  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,8 +10,13 @@ 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",
19
+ model: "lww",
14
20
  read(id) {
15
21
  return resources.get(id);
16
22
  },
@@ -19,9 +25,41 @@ function memoryStoreServer() {
19
25
  resources.set(id, { id, accessRules, data });
20
26
  },
21
27
  apply(change) {
22
- const r = get(change.id);
23
- r.data = change.update;
24
- for (const cb of listeners) cb(change);
28
+ commit(change);
29
+ },
30
+ open(id, openOpts) {
31
+ get(id);
32
+ const origin = openOpts?.origin ?? SERVER_ORIGIN;
33
+ const subs = /* @__PURE__ */ new Set();
34
+ const snap = () => resources.get(id)?.data;
35
+ return {
36
+ getSnapshot: snap,
37
+ subscribe: (cb) => {
38
+ const wrap = (c) => {
39
+ if (c.id === id) cb();
40
+ };
41
+ listeners.add(wrap);
42
+ const off = () => void listeners.delete(wrap);
43
+ subs.add(off);
44
+ return () => {
45
+ off();
46
+ subs.delete(off);
47
+ };
48
+ },
49
+ // LWW: every write replaces the whole value. delete/update must build a NEW value (read returns the
50
+ // LIVE object + commit swaps by reference), so the prior snapshot is never mutated in place.
51
+ set: (data) => commit({ id, update: data, origin }),
52
+ update: (partial) => {
53
+ const cur = snap();
54
+ const base = typeof cur === "object" && cur !== null ? cur : {};
55
+ commit({ id, update: { ...base, ...partial }, origin });
56
+ },
57
+ delete: (path) => commit({ id, update: removeAtPath(snap(), path), origin }),
58
+ close: () => {
59
+ for (const off of subs) off();
60
+ subs.clear();
61
+ }
62
+ };
25
63
  },
26
64
  setAccess(id, accessRules) {
27
65
  get(id).accessRules = accessRules;
@@ -71,6 +109,11 @@ var LwwReplica = class {
71
109
  const base = typeof this.value === "object" && this.value !== null ? this.value : {};
72
110
  return this.set({ ...base, ...partial });
73
111
  }
112
+ // Drop the value at `path` and replace (LWW). `removeAtPath` returns a fresh value, so `set`'s identity
113
+ // guard sees a change and the prior snapshot is never mutated in place.
114
+ delete(path) {
115
+ return this.set(removeAtPath(this.value, path));
116
+ }
74
117
  applyRemote(change) {
75
118
  if (change.origin === this.origin) return;
76
119
  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.7.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.7.0"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "tsup"