@dougongjs/reactive 0.3.0 → 0.4.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/README.md CHANGED
@@ -81,7 +81,7 @@ On each change to `source`: release the previous `lifetime`, then build a new on
81
81
  - 文档站 / Documentation: https://tangerg.github.io/dougong/
82
82
  - 仓库 / Repository: https://github.com/Tangerg/dougong
83
83
 
84
- > 早期开发阶段(0.0.x),当前不承诺向后兼容。需要 Node.js ≥ 22,或 Chrome / Edge 119、Firefox 121、Safari 17.4 及以上浏览器 / WebView。
85
- > Early development (0.0.x); no backward-compatibility promises yet. Requires Node.js ≥ 22, or Chrome / Edge 119, Firefox 121 or Safari 17.4 and later.
84
+ > 早期 0.x 开发阶段,当前不承诺向后兼容。需要 Node.js ≥ 22,或 Chrome / Edge 119、Firefox 121、Safari 17.4 及以上浏览器 / WebView。
85
+ > Early 0.x development; no backward-compatibility promises yet. Requires Node.js ≥ 22, or Chrome / Edge 119, Firefox 121 or Safari 17.4 and later.
86
86
 
87
87
  MIT
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ const w = v(
13
13
  Symbol.asyncDispose,
14
14
  "Symbol.asyncDispose"
15
15
  );
16
- function l(t, e) {
16
+ function p(t, e) {
17
17
  if (y(t))
18
18
  throw Promise.resolve(t).catch(() => {
19
19
  }), new TypeError(e);
@@ -28,46 +28,50 @@ class D {
28
28
  #n = { present: !1 };
29
29
  #r = !1;
30
30
  #t;
31
- #o;
32
31
  #c;
32
+ #o;
33
+ #a;
33
34
  constructor(e, s, i) {
34
35
  this.#e = { phase: "active", binding: { owner: e, source: s, observer: i } };
35
36
  }
36
37
  start() {
37
38
  const { owner: e, source: s } = this.#w(), i = s.get(), r = e.lifetime("observation");
38
39
  b(r), this.#i = r;
39
- const n = s.subscribe(() => this.#p());
40
- z(n, "Readable.subscribe()"), this.#s = n, this.#l(i, r), this.#n = { present: !0, value: i };
40
+ const n = s.subscribe(() => this.#u());
41
+ C(n, "Readable.subscribe()"), this.#s = n, this.#d(i, r), this.#n = { present: !0, value: i };
41
42
  const o = e.spawn((c) => this.#h(c));
42
- P(o), this.#t = o, o.result.then(
43
+ R(o), this.#t = o, o.result.then(
43
44
  () => this.#v(o),
44
45
  () => this.#v(o)
45
46
  );
46
47
  }
48
+ attachOwnerCleanup(e) {
49
+ this.#c = e;
50
+ }
47
51
  dispose() {
48
- if (this.#c) return this.#c;
52
+ if (this.#a) return this.#a;
49
53
  const e = Promise.withResolvers();
50
- return this.#c = e.promise, this.#y("disposed"), this.#o?.(), this.#f().then(e.resolve, e.reject), e.promise;
54
+ return this.#a = e.promise, this.#c = void 0, this.#y("disposed"), this.#o?.(), this.#p().then(e.resolve, e.reject), e.promise;
51
55
  }
52
- async #f() {
56
+ async #p() {
53
57
  const e = [];
54
- if (await a(this.#b(), e), await a(this.#g(), e), await a(this.#u(), e), e.length === 1) throw e[0];
58
+ if (await a(this.#b(), e), await a(this.#O(), e), await a(this.#f(), e), e.length === 1) throw e[0];
55
59
  if (e.length > 1) throw new AggregateError(e, "Observation cleanup failed");
56
60
  }
57
- #p() {
61
+ #u() {
58
62
  this.#e.phase === "active" && (this.#r = !0, this.#o?.());
59
63
  }
60
64
  async #h(e) {
61
65
  try {
62
66
  for (; this.#e.phase === "active" && !e.aborted; )
63
- for (await this.#a(e); this.#e.phase === "active" && !e.aborted && this.#r; )
64
- this.#r = !1, await this.#m();
67
+ for (await this.#m(e); this.#e.phase === "active" && !e.aborted && this.#r; )
68
+ this.#r = !1, await this.#g();
65
69
  } catch (s) {
66
70
  if (this.#e.phase !== "active") throw s;
67
- await this.#d([s], "Observation stopped after a replacement failed");
71
+ await this.#l([s], "Observation stopped after a replacement failed");
68
72
  }
69
73
  }
70
- #a(e) {
74
+ #m(e) {
71
75
  return this.#r || this.#e.phase !== "active" || e.aborted ? Promise.resolve() : new Promise((s) => {
72
76
  const i = () => {
73
77
  e.removeEventListener("abort", i), this.#o === i && (this.#o = void 0), s();
@@ -75,17 +79,17 @@ class D {
75
79
  this.#o = i, e.addEventListener("abort", i, { once: !0 }), (this.#r || this.#e.phase !== "active" || e.aborted) && i();
76
80
  });
77
81
  }
78
- async #m() {
82
+ async #g() {
79
83
  if (this.#e.phase !== "active") return;
80
84
  const e = this.#e.binding.source.get();
81
85
  if (this.#n.present && Object.is(e, this.#n.value)) return;
82
- const s = this.#u();
86
+ const s = this.#f();
83
87
  if (s)
84
88
  try {
85
89
  await s.dispose();
86
90
  } catch (r) {
87
91
  if (this.#e.phase !== "active") throw r;
88
- return this.#d(
92
+ return this.#l(
89
93
  [r],
90
94
  "Observation stopped because the previous lifetime could not be disposed"
91
95
  );
@@ -94,9 +98,9 @@ class D {
94
98
  const i = this.#e.binding.owner.lifetime("observation");
95
99
  b(i), this.#i = i;
96
100
  try {
97
- this.#l(e, i);
101
+ this.#d(e, i);
98
102
  } catch (r) {
99
- const n = this.#u();
103
+ const n = this.#f();
100
104
  try {
101
105
  n && await n.dispose();
102
106
  } catch (o) {
@@ -105,7 +109,7 @@ class D {
105
109
  [r, o],
106
110
  "Observation callback failed and its resources could not be cleaned up"
107
111
  );
108
- return this.#d(
112
+ return this.#l(
109
113
  [r, o],
110
114
  "Observation callback failed and its resources could not be cleaned up"
111
115
  );
@@ -114,27 +118,31 @@ class D {
114
118
  }
115
119
  this.#e.phase === "active" && (this.#n = { present: !0, value: e });
116
120
  }
117
- #l(e, s) {
121
+ #d(e, s) {
118
122
  const i = this.#w().observer(e, s);
119
- l(i, "Observers must be synchronous; use lifetime.spawn() for async work");
123
+ p(i, "Observers must be synchronous; use lifetime.spawn() for async work");
120
124
  }
121
125
  #b() {
122
126
  const e = this.#s;
123
127
  return this.#s = void 0, e;
124
128
  }
125
- #u() {
129
+ #f() {
126
130
  const e = this.#i;
127
131
  return this.#i = void 0, e;
128
132
  }
129
- #g() {
133
+ #O() {
130
134
  const e = this.#t;
131
135
  return this.#t = void 0, e;
132
136
  }
137
+ #k() {
138
+ const e = this.#c;
139
+ return this.#c = void 0, e;
140
+ }
133
141
  #v(e) {
134
142
  this.#t === e && (this.#t = void 0);
135
143
  }
136
- async #d(e, s) {
137
- throw this.#y("stopped"), this.#o?.(), await a(this.#b(), e), await a(this.#u(), e), e.length === 1 ? e[0] : new AggregateError(e, s);
144
+ async #l(e, s) {
145
+ throw this.#y("stopped"), this.#o?.(), await a(this.#b(), e), await a(this.#f(), e), this.#t = void 0, await a(this.#k(), e), e.length === 1 ? e[0] : new AggregateError(e, s);
138
146
  }
139
147
  #w() {
140
148
  const e = this.#e;
@@ -152,7 +160,7 @@ function L(t, e, s) {
152
160
  if (!t || typeof t.cleanup != "function" || typeof t.lifetime != "function" || typeof t.spawn != "function")
153
161
  throw new TypeError("observe() expects an observation owner");
154
162
  const i = new D(t, e, s), r = t.cleanup(() => i.dispose());
155
- R(r, "ObservationOwner.cleanup()");
163
+ z(r, "ObservationOwner.cleanup()"), i.attachOwnerCleanup(r);
156
164
  try {
157
165
  return i.start(), r;
158
166
  } catch (n) {
@@ -160,11 +168,11 @@ function L(t, e, s) {
160
168
  }), n;
161
169
  }
162
170
  }
163
- function z(t, e) {
171
+ function C(t, e) {
164
172
  if (!t || typeof t.dispose != "function" || typeof t[w] != "function")
165
173
  throw new TypeError(`${e} must return a Disposable`);
166
174
  }
167
- function R(t, e) {
175
+ function z(t, e) {
168
176
  if (!t || typeof t.dispose != "function" || typeof t[d] != "function")
169
177
  throw new TypeError(`${e} must return an AsyncDisposable`);
170
178
  }
@@ -172,7 +180,7 @@ function b(t) {
172
180
  if (!t || typeof t.dispose != "function" || typeof t[d] != "function" || typeof t.cleanup != "function" || typeof t.lifetime != "function" || typeof t.spawn != "function")
173
181
  throw new TypeError("ObservationOwner.lifetime() must return an ObservationLifetime");
174
182
  }
175
- function P(t) {
183
+ function R(t) {
176
184
  if (!t || typeof t.dispose != "function" || typeof t[d] != "function" || !y(t.result))
177
185
  throw new TypeError("ObservationOwner.spawn() must return an ObservationTask");
178
186
  }
@@ -185,11 +193,11 @@ async function a(t, e) {
185
193
  }
186
194
  }
187
195
  let u = 0, h, f;
188
- const p = /* @__PURE__ */ new WeakMap();
196
+ const l = /* @__PURE__ */ new WeakMap();
189
197
  function m(t) {
190
- return new j(t);
198
+ return new P(t);
191
199
  }
192
- class j {
200
+ class P {
193
201
  #e;
194
202
  constructor(e) {
195
203
  this.#e = e, Object.freeze(this);
@@ -202,7 +210,7 @@ class j {
202
210
  this.dispose();
203
211
  }
204
212
  }
205
- function A() {
213
+ function j() {
206
214
  const t = [];
207
215
  for (; h?.size; ) {
208
216
  const e = h;
@@ -224,7 +232,7 @@ function O(t, e) {
224
232
  const i = s.listener;
225
233
  if (i)
226
234
  try {
227
- i();
235
+ p(i(), "Signal subscribers must be synchronous");
228
236
  } catch (r) {
229
237
  e.push(r);
230
238
  }
@@ -244,7 +252,7 @@ function x(t) {
244
252
  let e;
245
253
  try {
246
254
  const s = t();
247
- l(s, "Reactive batches must be synchronous"), e = { ok: !0, value: s };
255
+ p(s, "Reactive batches must be synchronous"), e = { ok: !0, value: s };
248
256
  } catch (s) {
249
257
  e = { ok: !1, error: s };
250
258
  } finally {
@@ -252,7 +260,7 @@ function x(t) {
252
260
  }
253
261
  if (!u)
254
262
  try {
255
- A();
263
+ j();
256
264
  } catch (s) {
257
265
  e = e.ok ? { ok: !1, error: s } : { ok: !1, error: new AggregateError([e.error, s], "Reactive batch failed") };
258
266
  }
@@ -276,7 +284,7 @@ function q(t) {
276
284
  });
277
285
  }
278
286
  };
279
- return p.set(r, {
287
+ return l.set(r, {
280
288
  get version() {
281
289
  return s;
282
290
  },
@@ -286,53 +294,53 @@ function q(t) {
286
294
  }
287
295
  function B(t) {
288
296
  if (typeof t != "function") throw new TypeError("computed() expects a function");
289
- return new C(t).view;
297
+ return new A(t).view;
290
298
  }
291
- class C {
299
+ class A {
292
300
  #e;
293
301
  #s = /* @__PURE__ */ new Set();
294
302
  #i = /* @__PURE__ */ new Map();
295
303
  #n = { phase: "uninitialized" };
296
304
  #r = !1;
297
305
  #t = !0;
298
- #o = 0;
306
+ #c = 0;
299
307
  view;
300
308
  constructor(e) {
301
309
  this.#e = e, this.view = Object.freeze({
302
- get: () => this.#c(),
303
- subscribe: (s) => this.#f(s)
304
- }), p.set(this.view, this);
310
+ get: () => this.#o(),
311
+ subscribe: (s) => this.#a(s)
312
+ }), l.set(this.view, this);
305
313
  }
306
314
  get version() {
307
- return this.#o;
315
+ return this.#c;
308
316
  }
309
317
  refresh() {
310
- this.#a();
318
+ this.#h();
311
319
  }
312
- #c() {
313
- return E(this.view), this.#a();
320
+ #o() {
321
+ return E(this.view), this.#h();
314
322
  }
315
- #f(e) {
323
+ #a(e) {
316
324
  S(e);
317
325
  const s = { listener: e }, i = this.#s.size === 0;
318
326
  if (this.#s.add(s), i)
319
327
  try {
320
- this.#t = !0, this.#a();
328
+ this.#t = !0, this.#h();
321
329
  } catch (r) {
322
- throw this.#s.delete(s), this.#s.size || this.#h(), r;
330
+ throw this.#s.delete(s), this.#s.size || this.#u(), r;
323
331
  }
324
332
  return m(() => {
325
- s.listener = void 0, this.#s.delete(s), this.#s.size || this.#h();
333
+ s.listener = void 0, this.#s.delete(s), this.#s.size || this.#u();
326
334
  });
327
335
  }
328
336
  #p = () => {
329
337
  this.#t || (this.#t = !0, g(this.#s));
330
338
  };
331
- #h() {
339
+ #u() {
332
340
  for (const e of this.#i.values())
333
341
  e.subscription?.dispose(), e.subscription = void 0;
334
342
  }
335
- #a() {
343
+ #h() {
336
344
  const e = this.#n;
337
345
  if (e.phase === "cached" && !this.#t) {
338
346
  for (const n of this.#i.values())
@@ -347,14 +355,14 @@ class C {
347
355
  this.#r = !0, f = (n) => s.add(n);
348
356
  let r;
349
357
  try {
350
- r = this.#e(), l(r, "Computed signal calculations must be synchronous");
358
+ r = this.#e(), p(r, "Computed signal calculations must be synchronous");
351
359
  } finally {
352
360
  f = i, this.#r = !1;
353
361
  }
354
362
  for (const [n, o] of this.#i)
355
363
  s.has(n) || (o.subscription?.dispose(), this.#i.delete(n));
356
364
  for (const n of s) {
357
- const o = p.get(n);
365
+ const o = l.get(n);
358
366
  if (!o) continue;
359
367
  const c = this.#i.get(n) ?? {
360
368
  node: o,
@@ -363,7 +371,7 @@ class C {
363
371
  };
364
372
  c.version = o.version, this.#s.size && !c.subscription && (c.subscription = n.subscribe(this.#p)), this.#i.set(n, c);
365
373
  }
366
- return (e.phase === "uninitialized" || !Object.is(e.value, r)) && this.#o++, this.#n = { phase: "cached", value: r }, this.#t = !1, r;
374
+ return (e.phase === "uninitialized" || !Object.is(e.value, r)) && this.#c++, this.#n = { phase: "cached", value: r }, this.#t = !1, r;
367
375
  }
368
376
  }
369
377
  function S(t) {
@@ -1 +1 @@
1
- {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,QAAQ,EAEd,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,IAAI,CAAE,SAAQ,eAAe;IAChE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,OAAO,KAAK,eAAe,CAAC;IAC9D,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,mBAAmB,CAAC;IAC1D,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,CAAC;CAC9F;AAED,MAAM,WAAW,gBAAgB,CAAC,KAAK,SAAS,mBAAmB,GAAG,mBAAmB;IACvF,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,OAAO,KAAK,eAAe,CAAC;IAC9D,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,CAAC;CAC9F;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,KAAK,SAAS,mBAAmB,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,KAAK,IAAI,CAAC;AA+MjG;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,SAAS,mBAAmB,EAC1D,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EACnB,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,GAC3B,eAAe,CA0BjB"}
1
+ {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,QAAQ,EAEd,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,IAAI,CAAE,SAAQ,eAAe;IAChE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,OAAO,KAAK,eAAe,CAAC;IAC9D,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,mBAAmB,CAAC;IAC1D,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,CAAC;CAC9F;AAED,MAAM,WAAW,gBAAgB,CAAC,KAAK,SAAS,mBAAmB,GAAG,mBAAmB;IACvF,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,OAAO,KAAK,eAAe,CAAC;IAC9D,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,CAAC;CAC9F;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,KAAK,SAAS,mBAAmB,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,KAAK,IAAI,CAAC;AA+NjG;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,SAAS,mBAAmB,EAC1D,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EACnB,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,GAC3B,eAAe,CA2BjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dougongjs/reactive",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"