@sylwellsoftware/glue 0.2.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/dist/index.js CHANGED
@@ -1,137 +1,628 @@
1
- var g = Object.defineProperty;
2
- var v = (t, s, e) => s in t ? g(t, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[s] = e;
3
- var n = (t, s, e) => v(t, typeof s != "symbol" ? s + "" : s, e);
4
- import { B as w, F as p, a as y, E, b } from "./emitter-upM7NC28.js";
5
- import { D as _, c as x, d as D } from "./emitter-upM7NC28.js";
6
- class H extends w {
1
+ var H = Object.defineProperty;
2
+ var F = (t, r, e) => r in t ? H(t, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[r] = e;
3
+ var n = (t, r, e) => F(t, typeof r != "symbol" ? r + "" : r, e);
4
+ let x = 1;
5
+ class b {
6
+ constructor(r = {}) {
7
+ n(this, "id");
8
+ n(this, "timestamp");
9
+ n(this, "purpose");
10
+ n(this, "cause");
11
+ n(this, "value");
12
+ n(this, "parent");
13
+ n(this, "parentBubble");
14
+ n(this, "children", []);
15
+ n(this, "ownerType");
16
+ n(this, "ownerRef");
17
+ n(this, "strongOwner");
18
+ var s;
19
+ if (r == null || typeof r != "object" || Array.isArray(r))
20
+ throw new TypeError("EventBubble options must be an object");
21
+ this.id = `event-${x++}`, this.timestamp = r.timestamp ?? Date.now(), this.purpose = r.purpose ?? "unspecified", this.cause = r.cause ?? null, this.value = r.value, this.parent = r.parent ?? null, this.parentBubble = this.parent;
22
+ const e = r.owner;
23
+ this.ownerType = e == null ? null : $(e) ?? typeof e, B(e) && typeof WeakRef == "function" ? (this.ownerRef = new WeakRef(e), this.strongOwner = void 0) : (this.ownerRef = null, this.strongOwner = e), (s = this.parent) == null || s.registerChild(this);
24
+ }
25
+ get owner() {
26
+ var r;
27
+ return ((r = this.ownerRef) == null ? void 0 : r.deref()) ?? this.strongOwner;
28
+ }
29
+ registerChild(r) {
30
+ if (!(r instanceof b))
31
+ throw new TypeError("EventBubble children must be EventBubble instances");
32
+ this.children.includes(r) || this.children.push(r);
33
+ }
34
+ }
35
+ function B(t) {
36
+ return typeof t == "object" && t !== null || typeof t == "function";
37
+ }
38
+ function $(t) {
39
+ const r = Reflect.get(t, "constructor");
40
+ if (r == null || typeof r != "object" && typeof r != "function")
41
+ return;
42
+ const e = Reflect.get(r, "name");
43
+ return typeof e == "string" ? e : void 0;
44
+ }
45
+ const m = /* @__PURE__ */ new Set();
46
+ function C(t) {
47
+ if (typeof t != "function")
48
+ throw new TypeError("EventBus.subscribe requires a function");
49
+ m.add(t);
50
+ let r = !0;
51
+ return () => {
52
+ r && (r = !1, m.delete(t));
53
+ };
54
+ }
55
+ function V(t) {
56
+ for (const r of [...m]) r(t);
57
+ }
58
+ const w = Object.freeze({
59
+ subscribe: C,
60
+ emit: V,
61
+ emitBubble: V,
62
+ registerBubbleGraph(t) {
63
+ if (t == null || typeof t.addBubble != "function")
64
+ throw new TypeError("registerBubbleGraph requires an addBubble() method");
65
+ return C((r) => t.addBubble(r));
66
+ },
67
+ get hasSubscribers() {
68
+ return m.size > 0;
69
+ },
70
+ get subscriberCount() {
71
+ return m.size;
72
+ }
73
+ }), h = Object.freeze({
74
+ Error: "error",
75
+ Loading: "loading",
76
+ Initial: "initial",
77
+ Ready: "ready"
78
+ }), S = /* @__PURE__ */ new Map([
79
+ [h.Ready, 1],
80
+ [h.Initial, 2],
81
+ [h.Loading, 3],
82
+ [h.Error, 4]
83
+ ]);
84
+ function j(t) {
85
+ let r = h.Ready;
86
+ for (const e of t) {
87
+ if (!S.has(e))
88
+ throw new TypeError(`Unknown fetch state: ${String(e)}`);
89
+ if ((S.get(e) ?? 0) > (S.get(r) ?? 0) && (r = e), r === h.Error) break;
90
+ }
91
+ return r;
92
+ }
93
+ class g {
94
+ constructor(r, e = {}) {
95
+ n(this, "subscribers", /* @__PURE__ */ new Set());
96
+ n(this, "value");
97
+ n(this, "fetchState");
98
+ n(this, "error");
99
+ n(this, "equals");
100
+ n(this, "isDisposed", !1);
101
+ n(this, "owner");
102
+ n(this, "purpose");
103
+ n(this, "trace");
104
+ if (e == null || typeof e != "object" || Array.isArray(e))
105
+ throw new TypeError("Emitter options must be an object");
106
+ if (this.value = r, this.fetchState = e.fetchState ?? h.Ready, this.error = e.error ?? null, this.equals = e.equals ?? Object.is, this.owner = e.owner, this.purpose = e.purpose ?? this.constructor.name, this.trace = e.trace ?? !1, typeof this.equals != "function")
107
+ throw new TypeError("Emitter equals option must be a function");
108
+ R(this.fetchState);
109
+ }
110
+ subscribe(r, e = {}) {
111
+ if (this.isDisposed) throw new Error("Cannot subscribe to a disposed emitter");
112
+ if (typeof r != "function")
113
+ throw new TypeError("subscribe requires a function");
114
+ if (e == null || typeof e != "object" || Array.isArray(e))
115
+ throw new TypeError("subscribe options must be an object");
116
+ const { emitCurrent: s = !0, parentEvent: i = null } = e;
117
+ if (this.subscribers.add(r), s) {
118
+ const u = this.createEvent("subscribed", i, this.value);
119
+ r(this.notification(u));
120
+ }
121
+ let o = !0;
122
+ return () => {
123
+ o && (o = !1, this.subscribers.delete(r));
124
+ };
125
+ }
126
+ subscribeFutureValues(r) {
127
+ return this.subscribe(r, { emitCurrent: !1 });
128
+ }
129
+ get() {
130
+ return this.value;
131
+ }
132
+ getError() {
133
+ return this.error;
134
+ }
135
+ getFetchState() {
136
+ return this.fetchState;
137
+ }
138
+ get disposed() {
139
+ return this.isDisposed;
140
+ }
141
+ get subscriberCount() {
142
+ return this.subscribers.size;
143
+ }
144
+ map(r, e = {}) {
145
+ if (typeof r != "function") throw new TypeError("map requires a function");
146
+ return new D(
147
+ [this],
148
+ ([s]) => r(s),
149
+ {
150
+ ...e,
151
+ owner: e.owner ?? this.owner,
152
+ purpose: e.purpose ?? `${this.purpose}:map`,
153
+ trace: e.trace ?? this.trace
154
+ }
155
+ );
156
+ }
157
+ mapEach(r, e = {}) {
158
+ if (typeof r != "function") throw new TypeError("mapEach requires a function");
159
+ return new D([this], ([s]) => {
160
+ if (s == null) return s;
161
+ if (!Array.isArray(s))
162
+ throw new TypeError("mapEach source value must be an array");
163
+ return s.map((o, u) => o == null ? o : r(o, u));
164
+ }, {
165
+ ...e,
166
+ purpose: e.purpose ?? `${this.purpose}:mapEach`
167
+ });
168
+ }
169
+ dispose() {
170
+ this.isDisposed || (this.isDisposed = !0, this.subscribers.clear());
171
+ }
172
+ notification(r = null) {
173
+ return Object.freeze({
174
+ value: this.value,
175
+ fetchState: this.fetchState,
176
+ error: this.error,
177
+ event: r
178
+ });
179
+ }
180
+ notify(r = null) {
181
+ if (this.isDisposed) return;
182
+ const e = this.notification(r);
183
+ for (const s of [...this.subscribers]) s(e);
184
+ }
185
+ setSnapshot(r = {}) {
186
+ if (this.isDisposed) return !1;
187
+ const e = Object.hasOwn(r, "value") ? r.value : this.value, s = r.fetchState ?? this.fetchState, i = Object.hasOwn(r, "error") ? r.error : this.error, o = r.cause ?? "state changed", u = r.parentEvent ?? null;
188
+ if (R(s), !(!this.equals(this.value, e) || this.fetchState !== s || !Object.is(this.error, i))) return !1;
189
+ this.value = e, this.fetchState = s, this.error = i;
190
+ const c = this.createEvent(o, u, e);
191
+ return this.notify(c), !0;
192
+ }
193
+ createEvent(r, e = null, s = this.value) {
194
+ if (!this.trace && !e && !w.hasSubscribers) return null;
195
+ const i = new b({
196
+ owner: this.owner ?? this,
197
+ purpose: this.purpose,
198
+ value: s,
199
+ cause: r,
200
+ parent: e
201
+ });
202
+ return e || w.emit(i), i;
203
+ }
204
+ }
205
+ class D extends g {
206
+ constructor(e, s, i = {}) {
207
+ const { computeFetchState: o = j, ...u } = i;
208
+ super(void 0, {
209
+ ...u,
210
+ fetchState: h.Initial,
211
+ error: null
212
+ });
213
+ n(this, "sources");
214
+ n(this, "sourceUnsubscribers", []);
215
+ n(this, "compute");
216
+ n(this, "computeFetchState");
217
+ this.sources = [], this.compute = s, this.computeFetchState = o, this.setSourcesAndCompute(e, s, { notify: !1 });
218
+ }
219
+ setSourcesAndCompute(e, s = this.compute, i = {}) {
220
+ if (this.isDisposed) throw new Error("Cannot update a disposed derived emitter");
221
+ if (!Array.isArray(e) || e.some((o) => !k(o)))
222
+ throw new TypeError("DerivedEmitter sources must be an array of emitters");
223
+ if (typeof s != "function")
224
+ throw new TypeError("DerivedEmitter compute must be a function");
225
+ return this.releaseSources(), this.sources = [...e], this.compute = s, this.sourceUnsubscribers = this.sources.map(
226
+ (o) => o.subscribe(({ event: u }) => this.recompute(u), { emitCurrent: !1 })
227
+ ), this.recompute(i.parentEvent ?? null, i.notify ?? !0), this;
228
+ }
229
+ dispose() {
230
+ this.isDisposed || (this.releaseSources(), super.dispose());
231
+ }
232
+ releaseSources() {
233
+ for (const e of this.sourceUnsubscribers) e();
234
+ this.sourceUnsubscribers = [];
235
+ }
236
+ recompute(e = null, s = !0) {
237
+ const i = this.sources.map((d) => d.get()), o = this.sources.map((d) => d.getFetchState()), u = this.sources.map((d, v) => ({ sourceIndex: v, error: d.getError() })).filter((d) => d.error != null);
238
+ let a, c = null;
239
+ try {
240
+ a = this.compute(i);
241
+ } catch (d) {
242
+ c = d, a = void 0;
243
+ }
244
+ const f = c == null ? u : [...u, { sourceIndex: null, error: c }], p = _(this.error, f);
245
+ let l = this.computeFetchState(o);
246
+ if (R(l), (c != null || u.length > 0) && (l = h.Error), !s) {
247
+ this.value = a, this.fetchState = l, this.error = p;
248
+ return;
249
+ }
250
+ this.setSnapshot({
251
+ value: a,
252
+ fetchState: l,
253
+ error: p,
254
+ cause: "derived source changed",
255
+ parentEvent: e
256
+ });
257
+ }
258
+ }
259
+ function _(t, r) {
260
+ return r.length === 0 ? null : t != null && t.length === r.length && t.every((e, s) => {
261
+ var i, o;
262
+ return e.sourceIndex === ((i = r[s]) == null ? void 0 : i.sourceIndex) && Object.is(e.error, (o = r[s]) == null ? void 0 : o.error);
263
+ }) ? t : Object.freeze(r.map((e) => Object.freeze(e)));
264
+ }
265
+ function k(t) {
266
+ return (typeof t != "object" || t === null) && typeof t != "function" ? !1 : typeof Reflect.get(t, "get") == "function" && typeof Reflect.get(t, "getFetchState") == "function" && typeof Reflect.get(t, "getError") == "function" && typeof Reflect.get(t, "subscribe") == "function";
267
+ }
268
+ function R(t) {
269
+ j([t]);
270
+ }
271
+ class U extends g {
272
+ constructor(r, e = {}) {
273
+ super(r, e);
274
+ }
275
+ setWithState(r, e = h.Ready, s = null, i = null) {
276
+ const o = i instanceof b ? i : null, u = o ? "set called" : i ?? "set called";
277
+ return this.setSnapshot({ value: r, fetchState: e, error: s, cause: u, parentEvent: o });
278
+ }
279
+ set(r, e = null) {
280
+ return this.setWithState(r, h.Ready, null, e);
281
+ }
282
+ }
283
+ class M extends Error {
284
+ constructor() {
285
+ super("AsyncCommand is already running"), this.name = "AsyncCommandConcurrencyError";
286
+ }
287
+ }
288
+ class fe extends g {
289
+ constructor(e) {
290
+ N(e);
291
+ const {
292
+ execute: s,
293
+ concurrency: i = "ignore",
294
+ mapError: o = (f) => f,
295
+ owner: u,
296
+ purpose: a = "async command",
297
+ trace: c
298
+ } = e;
299
+ if (W(i), typeof o != "function")
300
+ throw new TypeError("AsyncCommand mapError must be a function");
301
+ super(void 0, {
302
+ fetchState: h.Initial,
303
+ error: null,
304
+ owner: u,
305
+ purpose: a,
306
+ ...c === void 0 ? {} : { trace: c }
307
+ });
308
+ n(this, "execute");
309
+ n(this, "concurrency");
310
+ n(this, "isRunning");
311
+ n(this, "mapError");
312
+ n(this, "runningEmitter");
313
+ n(this, "requestId", 0);
314
+ n(this, "abortController", null);
315
+ n(this, "lastSuccessfulValue");
316
+ n(this, "hasSuccessfulValue", !1);
317
+ /** Exposed for deterministic tests; consumers should use run()/abort(). */
318
+ n(this, "_activeRequest", null);
319
+ this.execute = s, this.concurrency = i, this.mapError = o, this.runningEmitter = new U(!1, {
320
+ owner: u ?? this,
321
+ purpose: `${a}:running`,
322
+ ...c === void 0 ? {} : { trace: c }
323
+ }), this.isRunning = this.runningEmitter;
324
+ }
325
+ run(e, s = "command run") {
326
+ var p;
327
+ if (this.isDisposed) return Promise.resolve(void 0);
328
+ if (this._activeRequest != null) {
329
+ if (this.concurrency === "ignore") return this._activeRequest;
330
+ if (this.concurrency === "reject")
331
+ return Promise.reject(new M());
332
+ (p = this.abortController) == null || p.abort();
333
+ }
334
+ const i = ++this.requestId, o = G();
335
+ this.abortController = o;
336
+ const u = s instanceof b ? s : null, a = u ? "parent command requested" : s;
337
+ this.setSnapshot({
338
+ value: this.lastSuccessfulValue,
339
+ fetchState: h.Loading,
340
+ error: null,
341
+ cause: a,
342
+ parentEvent: u
343
+ });
344
+ const c = this.createEvent("command execute", u, e);
345
+ this.runningEmitter.set(!0, c ?? a);
346
+ const f = Promise.resolve().then(() => this.execute(e, {
347
+ signal: o.signal,
348
+ event: c
349
+ })).then((l) => {
350
+ if (this.isCurrentRequest(i, o))
351
+ return this.lastSuccessfulValue = l, this.hasSuccessfulValue = !0, this.setSnapshot({
352
+ value: l,
353
+ fetchState: h.Ready,
354
+ error: null,
355
+ cause: "command succeeded",
356
+ parentEvent: c
357
+ }), l;
358
+ }).catch((l) => {
359
+ this.isCurrentRequest(i, o) && this.setSnapshot({
360
+ value: this.lastSuccessfulValue,
361
+ fetchState: h.Error,
362
+ error: this.mapCommandError(l),
363
+ cause: "command failed",
364
+ parentEvent: c
365
+ });
366
+ }).finally(() => {
367
+ this.isCurrentRequest(i, o) && (this.abortController = null, this._activeRequest = null, this.runningEmitter.set(!1, c ?? "command settled"));
368
+ });
369
+ return this._activeRequest = f, f;
370
+ }
371
+ abort(e = "command aborted") {
372
+ if (this.isDisposed || this.abortController == null) return !1;
373
+ const s = e instanceof b ? e : null, i = s ? "parent command aborted" : e;
374
+ return this.requestId += 1, this.abortController.abort(), this.abortController = null, this._activeRequest = null, this.runningEmitter.set(!1, s ?? i), this.setSnapshot({
375
+ value: this.lastSuccessfulValue,
376
+ fetchState: this.hasSuccessfulValue ? h.Ready : h.Initial,
377
+ error: null,
378
+ cause: i,
379
+ parentEvent: s
380
+ }), !0;
381
+ }
382
+ reset(e = "command reset") {
383
+ if (this.isDisposed) return;
384
+ this.abort(e), this.lastSuccessfulValue = void 0, this.hasSuccessfulValue = !1;
385
+ const s = e instanceof b ? e : null;
386
+ this.setSnapshot({
387
+ value: void 0,
388
+ fetchState: h.Initial,
389
+ error: null,
390
+ cause: s ? "parent command reset" : e,
391
+ parentEvent: s
392
+ });
393
+ }
394
+ dispose() {
395
+ var e;
396
+ this.isDisposed || (this.requestId += 1, (e = this.abortController) == null || e.abort(), this.abortController = null, this._activeRequest = null, this.runningEmitter.set(!1, "command disposed"), this.runningEmitter.dispose(), super.dispose());
397
+ }
398
+ isCurrentRequest(e, s) {
399
+ return !this.isDisposed && e === this.requestId && s === this.abortController && !s.signal.aborted;
400
+ }
401
+ mapCommandError(e) {
402
+ try {
403
+ return this.mapError(e);
404
+ } catch (s) {
405
+ return s;
406
+ }
407
+ }
408
+ }
409
+ function N(t) {
410
+ if (t == null || typeof t != "object" || Array.isArray(t))
411
+ throw new TypeError("AsyncCommand options must be an object");
412
+ if (typeof t.execute != "function")
413
+ throw new TypeError("AsyncCommand execute must be a function");
414
+ }
415
+ function W(t) {
416
+ if (t !== "ignore" && t !== "replace" && t !== "reject")
417
+ throw new TypeError(`Unknown AsyncCommand concurrency policy: ${t}`);
418
+ }
419
+ function G() {
420
+ const t = Reflect.get(globalThis, "AbortController");
421
+ if (typeof t != "function")
422
+ throw new Error("AsyncCommand requires AbortController in this runtime");
423
+ return new t();
424
+ }
425
+ class I extends g {
7
426
  constructor(e) {
8
427
  if (e == null || typeof e != "object" || Array.isArray(e))
9
428
  throw new TypeError("LiveQuery options must be an object");
10
429
  const {
11
- handler: r,
430
+ handler: s,
12
431
  args: i = {},
13
432
  autoFetch: o = !0,
14
- keepPreviousValue: f = !0,
15
- owner: l,
16
- purpose: c = "live query",
17
- trace: u
433
+ keepPreviousValue: u = !0,
434
+ polling: a,
435
+ owner: c,
436
+ purpose: f = "live query",
437
+ trace: p
18
438
  } = e;
19
- if (r == null || typeof r.fetch != "function")
439
+ if (s == null || typeof s.fetch != "function")
20
440
  throw new TypeError("LiveQuery handler must implement fetch()");
21
- R(i);
441
+ X(i), a != null && K(a);
22
442
  super(void 0, {
23
- fetchState: p.Initial,
443
+ fetchState: h.Initial,
24
444
  error: null,
25
- owner: l,
26
- purpose: c,
27
- ...u === void 0 ? {} : { trace: u }
445
+ owner: c,
446
+ purpose: f,
447
+ ...p === void 0 ? {} : { trace: p }
28
448
  });
29
449
  n(this, "handler");
30
450
  n(this, "args");
31
451
  n(this, "keepPreviousValue");
32
452
  n(this, "lastSuccessfulValue");
453
+ n(this, "hasSuccessfulValue", !1);
33
454
  n(this, "argumentUnsubscribers");
455
+ n(this, "pollingUnsubscribers", []);
456
+ n(this, "polling");
457
+ n(this, "pollingScheduler");
458
+ n(this, "pollingHandle", null);
34
459
  n(this, "requestId", 0);
35
460
  n(this, "abortController", null);
36
461
  /** Exposed for deterministic tests; consumers should use refresh()/retry(). */
37
462
  n(this, "_activeRequest", null);
38
- this.handler = r, this.args = { ...i }, this.keepPreviousValue = f, this.lastSuccessfulValue = void 0, this.argumentUnsubscribers = Object.values(this.args).map(
39
- (h) => h.subscribe(({ event: a }) => {
40
- this.refresh(a);
463
+ this.handler = s, this.args = { ...i }, this.keepPreviousValue = u, this.polling = a, this.pollingScheduler = (a == null ? void 0 : a.scheduler) ?? J, this.lastSuccessfulValue = void 0, this.argumentUnsubscribers = Object.values(this.args).map(
464
+ (l) => l.subscribe(({ event: d }) => {
465
+ this.refresh(d);
41
466
  }, { emitCurrent: !1 })
42
- ), o && (this._activeRequest = this.refresh("initial fetch"));
467
+ ), a != null && this.initializePolling(a), o && (this._activeRequest = this.refresh("initial fetch")), this.scheduleNextPoll();
43
468
  }
44
469
  get argumentValues() {
45
470
  return Object.fromEntries(
46
- Object.entries(this.args).map(([e, r]) => [e, r.get()])
471
+ Object.entries(this.args).map(([e, s]) => [e, s.get()])
47
472
  );
48
473
  }
49
474
  refresh(e = "refresh") {
50
- var h;
475
+ var p;
51
476
  if (this.isDisposed) return Promise.resolve(void 0);
52
- const r = ++this.requestId;
53
- (h = this.abortController) == null || h.abort();
54
- const i = q();
477
+ const s = ++this.requestId;
478
+ (p = this.abortController) == null || p.abort();
479
+ const i = Y();
55
480
  this.abortController = i;
56
- const o = e instanceof y ? e : null, f = o ? "query arguments changed" : e, l = this.keepPreviousValue ? this.lastSuccessfulValue : void 0;
481
+ const o = e instanceof b ? e : null, u = o ? "query arguments changed" : e, a = this.keepPreviousValue ? this.lastSuccessfulValue : void 0;
57
482
  this.setSnapshot({
58
- value: l,
59
- fetchState: p.Loading,
483
+ value: a,
484
+ fetchState: h.Loading,
60
485
  error: null,
61
- cause: f,
486
+ cause: u,
62
487
  parentEvent: o
63
488
  });
64
- const c = this.createEvent("query fetch", o, this.argumentValues), u = Promise.resolve().then(() => this.handler.fetch(this.argumentValues, {
489
+ const c = this.createEvent("query fetch", o, this.argumentValues), f = Promise.resolve().then(() => this.handler.fetch(this.argumentValues, {
65
490
  signal: i.signal,
66
491
  event: c
67
- })).then((a) => {
68
- if (this.isCurrentRequest(r, i))
69
- return this.lastSuccessfulValue = a, this.setSnapshot({
70
- value: a,
71
- fetchState: p.Ready,
492
+ })).then((l) => {
493
+ if (this.isCurrentRequest(s, i))
494
+ return this.lastSuccessfulValue = l, this.hasSuccessfulValue = !0, this.setSnapshot({
495
+ value: l,
496
+ fetchState: h.Ready,
72
497
  error: null,
73
498
  cause: "query succeeded",
74
499
  parentEvent: c
75
- }), a;
76
- }).catch((a) => {
77
- !this.isCurrentRequest(r, i) || S(a) || this.setSnapshot({
500
+ }), l;
501
+ }).catch((l) => {
502
+ !this.isCurrentRequest(s, i) || Z(l) || this.setSnapshot({
78
503
  value: this.keepPreviousValue ? this.lastSuccessfulValue : void 0,
79
- fetchState: p.Error,
80
- error: a,
504
+ fetchState: h.Error,
505
+ error: l,
81
506
  cause: "query failed",
82
507
  parentEvent: c
83
508
  });
84
509
  }).finally(() => {
85
- this.isCurrentRequest(r, i) && (this.abortController = null, this._activeRequest = null);
510
+ this.isCurrentRequest(s, i) && (this.abortController = null, this._activeRequest = null);
86
511
  });
87
- return this._activeRequest = u, u;
512
+ return this._activeRequest = f, f;
88
513
  }
89
514
  retry(e = "retry") {
90
515
  return this.refresh(e);
91
516
  }
517
+ abort(e = "query aborted") {
518
+ if (this.isDisposed || this.abortController == null) return;
519
+ this.requestId += 1, this.abortController.abort(), this.abortController = null, this._activeRequest = null;
520
+ const s = e instanceof b ? e : null;
521
+ this.setSnapshot({
522
+ value: this.hasSuccessfulValue ? this.lastSuccessfulValue : void 0,
523
+ fetchState: this.hasSuccessfulValue ? h.Ready : h.Initial,
524
+ error: null,
525
+ cause: s == null ? e : "query aborted",
526
+ parentEvent: s
527
+ });
528
+ }
92
529
  dispose() {
93
530
  var e;
94
531
  if (!this.isDisposed) {
95
- this.requestId += 1, (e = this.abortController) == null || e.abort(), this.abortController = null, this._activeRequest = null;
96
- for (const r of this.argumentUnsubscribers) r();
97
- this.argumentUnsubscribers = [], super.dispose();
532
+ this.requestId += 1, (e = this.abortController) == null || e.abort(), this.abortController = null, this._activeRequest = null, this.cancelScheduledPoll();
533
+ for (const s of this.argumentUnsubscribers) s();
534
+ this.argumentUnsubscribers = [];
535
+ for (const s of this.pollingUnsubscribers) s();
536
+ this.pollingUnsubscribers = [], super.dispose();
98
537
  }
99
538
  }
100
- isCurrentRequest(e, r) {
101
- return !this.isDisposed && e === this.requestId && r === this.abortController && !r.signal.aborted;
539
+ initializePolling(e) {
540
+ for (const s of [e.intervalMs, e.enabled])
541
+ T(s) && this.pollingUnsubscribers.push(s.subscribe(() => {
542
+ q(y(e.intervalMs)), Q(y(e.enabled, !0)), this.cancelScheduledPoll(), this.scheduleNextPoll();
543
+ }, { emitCurrent: !1 }));
544
+ }
545
+ scheduleNextPoll() {
546
+ if (this.isDisposed || this.polling == null || this.pollingHandle != null || !y(this.polling.enabled, !0)) return;
547
+ const e = y(this.polling.intervalMs);
548
+ q(e), this.pollingHandle = this.pollingScheduler.schedule(() => {
549
+ this.pollingHandle = null, this.scheduleNextPoll(), this._activeRequest == null && this.refresh("poll");
550
+ }, e);
551
+ }
552
+ cancelScheduledPoll() {
553
+ this.pollingHandle != null && (this.pollingScheduler.cancel(this.pollingHandle), this.pollingHandle = null);
554
+ }
555
+ isCurrentRequest(e, s) {
556
+ return !this.isDisposed && e === this.requestId && s === this.abortController && !s.signal.aborted;
102
557
  }
103
558
  }
104
- function R(t) {
559
+ const J = {
560
+ schedule(t, r) {
561
+ const e = Reflect.get(globalThis, "setTimeout");
562
+ if (typeof e != "function")
563
+ throw new Error("LiveQuery polling requires an injected scheduler in this runtime");
564
+ return Reflect.apply(e, globalThis, [t, r]);
565
+ },
566
+ cancel(t) {
567
+ const r = Reflect.get(globalThis, "clearTimeout");
568
+ typeof r == "function" && Reflect.apply(r, globalThis, [t]);
569
+ }
570
+ };
571
+ function T(t) {
572
+ return t != null && (typeof t == "object" || typeof t == "function") && typeof Reflect.get(t, "get") == "function" && typeof Reflect.get(t, "subscribe") == "function";
573
+ }
574
+ function O(t, r) {
575
+ if (typeof t != "number" && typeof t != "boolean" && !T(t))
576
+ throw new TypeError(`LiveQuery polling ${r} must be a value or emitter`);
577
+ }
578
+ function K(t) {
579
+ if (t == null || typeof t != "object" || Array.isArray(t))
580
+ throw new TypeError("LiveQuery polling options must be an object");
581
+ if (O(t.intervalMs, "intervalMs"), t.enabled !== void 0 && O(t.enabled, "enabled"), q(y(t.intervalMs)), Q(y(t.enabled, !0)), t.scheduler != null && (typeof t.scheduler.schedule != "function" || typeof t.scheduler.cancel != "function"))
582
+ throw new TypeError("LiveQuery polling scheduler must implement schedule() and cancel()");
583
+ }
584
+ function y(t, r) {
585
+ return t === void 0 ? r : T(t) ? t.get() : t;
586
+ }
587
+ function q(t) {
588
+ if (!Number.isFinite(t) || t <= 0)
589
+ throw new RangeError("LiveQuery polling intervalMs must be a finite positive number");
590
+ }
591
+ function Q(t) {
592
+ if (typeof t != "boolean")
593
+ throw new TypeError("LiveQuery polling enabled must be a boolean");
594
+ }
595
+ function X(t) {
105
596
  if (t == null || typeof t != "object" || Array.isArray(t))
106
597
  throw new TypeError("LiveQuery args must be a named record of emitters");
107
- for (const [s, e] of Object.entries(t))
598
+ for (const [r, e] of Object.entries(t))
108
599
  if (e == null || typeof Reflect.get(e, "get") != "function" || typeof Reflect.get(e, "subscribe") != "function")
109
- throw new TypeError(`LiveQuery argument ${s} must be an emitter`);
600
+ throw new TypeError(`LiveQuery argument ${r} must be an emitter`);
110
601
  }
111
- function q() {
602
+ function Y() {
112
603
  const t = Reflect.get(globalThis, "AbortController");
113
604
  if (typeof t != "function")
114
605
  throw new Error("LiveQuery requires AbortController in this runtime");
115
606
  return new t();
116
607
  }
117
- function S(t) {
608
+ function Z(t) {
118
609
  return t instanceof Error && t.name === "AbortError";
119
610
  }
120
- class z extends E {
121
- constructor(e, r, i = {}) {
611
+ class pe extends U {
612
+ constructor(e, s, i = {}) {
122
613
  if (typeof e != "string" || e.length === 0)
123
614
  throw new TypeError("QueryArg name must be a non-empty string");
124
- if (r == null || typeof r.get != "function" || typeof r.subscribe != "function")
615
+ if (s == null || typeof s.get != "function" || typeof s.subscribe != "function")
125
616
  throw new TypeError("QueryArg source must be an emitter");
126
- super(r.get(), {
617
+ super(s.get(), {
127
618
  ...i,
128
- fetchState: r.getFetchState(),
129
- error: r.getError(),
619
+ fetchState: s.getFetchState(),
620
+ error: s.getError(),
130
621
  purpose: i.purpose ?? `query argument: ${e}`
131
622
  });
132
623
  n(this, "name");
133
624
  n(this, "sourceUnsubscribe");
134
- this.name = e, this.sourceUnsubscribe = r.subscribe((o) => {
625
+ this.name = e, this.sourceUnsubscribe = s.subscribe((o) => {
135
626
  this.setWithState(
136
627
  o.value,
137
628
  o.fetchState,
@@ -145,118 +636,277 @@ class z extends E {
145
636
  this.isDisposed || ((e = this.sourceUnsubscribe) == null || e.call(this), this.sourceUnsubscribe = null, super.dispose());
146
637
  }
147
638
  }
148
- class T {
149
- fetch(s, e = {}) {
639
+ class ee {
640
+ fetch(r, e = {}) {
150
641
  throw new Error("fetch() must be implemented");
151
642
  }
152
643
  }
153
- class U extends Error {
644
+ class te extends Error {
154
645
  constructor(e) {
155
646
  super(`HTTP ${e ?? "unknown"}`);
156
647
  n(this, "status");
157
648
  this.name = "HttpError", this.status = e;
158
649
  }
159
650
  }
160
- class I extends T {
651
+ class re extends ee {
161
652
  constructor(e) {
162
653
  super();
163
654
  n(this, "url");
164
655
  n(this, "baseUrl");
165
656
  n(this, "fetchImplementation");
166
657
  n(this, "serialize");
658
+ n(this, "parseResult");
167
659
  n(this, "trace");
168
- const r = typeof e == "string" ? { url: e } : e;
169
- if (r == null || typeof r != "object")
660
+ const s = typeof e == "string" ? { url: e } : e;
661
+ if (s == null || typeof s != "object")
170
662
  throw new TypeError("RestQueryHandler requires a URL or options object");
171
- if (typeof r.url != "string" || r.url.length === 0)
663
+ if (typeof s.url != "string" || s.url.length === 0)
172
664
  throw new TypeError("RestQueryHandler url must be a non-empty string");
173
- if (this.url = r.url, this.baseUrl = r.baseUrl ?? V(), this.fetchImplementation = r.fetch ?? j(), this.serialize = r.serialize ?? A, this.trace = r.trace ?? !1, typeof this.fetchImplementation != "function")
665
+ if (this.url = s.url, this.baseUrl = s.baseUrl ?? ie(), this.fetchImplementation = s.fetch ?? oe(), this.serialize = s.serialize ?? se, this.parseResult = s.parseResult, this.trace = s.trace ?? !1, typeof this.fetchImplementation != "function")
174
666
  throw new TypeError("RestQueryHandler requires an injected fetch implementation");
175
667
  if (typeof this.serialize != "function")
176
668
  throw new TypeError("RestQueryHandler serialize must be a function");
669
+ if (this.parseResult !== void 0 && typeof this.parseResult != "function")
670
+ throw new TypeError("RestQueryHandler parseResult must be a function");
177
671
  }
178
- async fetch(e, r = {}) {
672
+ async fetch(e, s = {}) {
179
673
  if (e == null || typeof e != "object" || Array.isArray(e))
180
674
  throw new TypeError("REST query args must be a named record");
181
- const i = Q(this.url, this.baseUrl), o = this.serialize(i, e) ?? i, f = d();
182
- if (!(o instanceof f))
675
+ const i = ne(this.url, this.baseUrl), o = this.serialize(i, e) ?? i, u = P();
676
+ if (!(o instanceof u))
183
677
  throw new TypeError("REST serializer must mutate or return a URL");
184
- const l = r.event ?? null;
185
- if (this.trace || l || b.hasSubscribers) {
186
- const h = new y({
678
+ const a = s.event ?? null;
679
+ if (this.trace || a || w.hasSubscribers) {
680
+ const l = new b({
187
681
  owner: this,
188
682
  purpose: "REST fetch",
189
683
  value: o.toString(),
190
684
  cause: "fetch called",
191
- parent: l
685
+ parent: a
192
686
  });
193
- l || b.emit(h);
687
+ a || w.emit(l);
194
688
  }
195
- const c = r.signal === void 0 ? {} : { signal: r.signal }, u = await this.fetchImplementation(o.toString(), c);
196
- if (!(u != null && u.ok)) throw new U(u == null ? void 0 : u.status);
197
- return await u.json();
689
+ const c = s.signal === void 0 ? {} : { signal: s.signal }, f = await this.fetchImplementation(o.toString(), c);
690
+ if (!(f != null && f.ok)) throw new te(f == null ? void 0 : f.status);
691
+ const p = await f.json();
692
+ return this.parseResult == null ? p : this.parseResult(p);
198
693
  }
199
694
  }
200
- function A(t, s) {
201
- for (const [e, r] of Object.entries(s))
202
- m(t.searchParams, e, r);
695
+ function se(t, r) {
696
+ for (const [e, s] of Object.entries(r))
697
+ L(t.searchParams, e, s);
203
698
  return t;
204
699
  }
205
- function m(t, s, e) {
700
+ function L(t, r, e) {
206
701
  if (e !== void 0) {
207
702
  if (e === null) {
208
- t.append(s, "");
703
+ t.append(r, "");
209
704
  return;
210
705
  }
211
706
  if (Array.isArray(e)) {
212
- for (const r of e) m(t, s, r);
707
+ for (const s of e) L(t, r, s);
213
708
  return;
214
709
  }
215
710
  if (typeof e == "object") {
216
- t.append(s, JSON.stringify(e));
711
+ t.append(r, JSON.stringify(e));
217
712
  return;
218
713
  }
219
- t.append(s, String(e));
714
+ t.append(r, String(e));
220
715
  }
221
716
  }
222
- function Q(t, s) {
223
- const e = d();
717
+ function ne(t, r) {
718
+ const e = P();
224
719
  try {
225
720
  return new e(t);
226
- } catch (r) {
227
- if (s == null)
228
- throw new TypeError(`Relative REST URL requires baseUrl: ${t}`, { cause: r });
229
- return new e(t, s);
721
+ } catch (s) {
722
+ if (r == null)
723
+ throw new TypeError(`Relative REST URL requires baseUrl: ${t}`, { cause: s });
724
+ return new e(t, r);
230
725
  }
231
726
  }
232
- function d() {
727
+ function P() {
233
728
  const t = Reflect.get(globalThis, "URL");
234
729
  if (typeof t != "function")
235
730
  throw new Error("RestQueryHandler requires URL in this runtime");
236
731
  return t;
237
732
  }
238
- function V() {
733
+ function ie() {
239
734
  const t = Reflect.get(globalThis, "location");
240
735
  if (t == null || typeof t != "object" && typeof t != "function")
241
736
  return;
242
- const s = Reflect.get(t, "href");
243
- return typeof s == "string" ? s : void 0;
737
+ const r = Reflect.get(t, "href");
738
+ return typeof r == "string" ? r : void 0;
244
739
  }
245
- function j() {
740
+ function oe() {
246
741
  return Reflect.get(globalThis, "fetch");
247
742
  }
743
+ class ue {
744
+ constructor(r) {
745
+ n(this, "handler");
746
+ n(this, "queryOptions");
747
+ if (r == null || typeof r != "object" || Array.isArray(r))
748
+ throw new TypeError("QueryEndpoint options must be an object");
749
+ if (r.handler == null || typeof r.handler.fetch != "function")
750
+ throw new TypeError("QueryEndpoint handler must implement fetch()");
751
+ const e = r.query ?? {};
752
+ E(e), this.handler = r.handler, this.queryOptions = Object.freeze({ ...e }), Object.freeze(this);
753
+ }
754
+ open(r, e = {}) {
755
+ return A(r), E(e), new I({
756
+ handler: this.handler,
757
+ args: r,
758
+ ...this.queryOptions,
759
+ ...e
760
+ });
761
+ }
762
+ }
763
+ function de(t) {
764
+ return new ue(t);
765
+ }
766
+ class ce {
767
+ constructor(r) {
768
+ n(this, "handler");
769
+ n(this, "queryOptions");
770
+ if (r == null || typeof r != "object" || Array.isArray(r))
771
+ throw new TypeError("RestEndpoint options must be an object");
772
+ const { query: e = {}, ...s } = r;
773
+ E(e, "RestEndpoint query options"), this.handler = new re(s), this.queryOptions = Object.freeze({ ...e }), Object.freeze(this);
774
+ }
775
+ open(r, e = {}) {
776
+ return A(r), E(e), new I({
777
+ handler: this.handler,
778
+ args: r,
779
+ ...this.queryOptions,
780
+ ...e
781
+ });
782
+ }
783
+ }
784
+ function be(t) {
785
+ return new ce(t);
786
+ }
787
+ class le {
788
+ constructor(r) {
789
+ n(this, "apply");
790
+ n(this, "purpose");
791
+ if (r == null || typeof r != "object" || Array.isArray(r))
792
+ throw new TypeError("DerivedEndpoint options must be an object");
793
+ if (typeof r.apply != "function")
794
+ throw new TypeError("DerivedEndpoint apply must be a function");
795
+ this.apply = r.apply, this.purpose = r.purpose ?? "derived endpoint", Object.freeze(this);
796
+ }
797
+ open(r) {
798
+ return new ae({
799
+ ...r,
800
+ apply: this.apply,
801
+ purpose: r.purpose ?? this.purpose
802
+ });
803
+ }
804
+ }
805
+ function ye(t) {
806
+ return new le(t);
807
+ }
808
+ class ae extends g {
809
+ constructor(e) {
810
+ if (e == null || typeof e != "object" || Array.isArray(e))
811
+ throw new TypeError("DerivedLiveResult options must be an object");
812
+ if (A(e.args), !z(e.source))
813
+ throw new TypeError("DerivedLiveResult source must be an emitter");
814
+ if (typeof e.apply != "function")
815
+ throw new TypeError("DerivedLiveResult apply must be a function");
816
+ super(void 0, {
817
+ fetchState: h.Initial,
818
+ error: null,
819
+ owner: e.owner,
820
+ ...e.purpose === void 0 ? {} : { purpose: e.purpose },
821
+ ...e.trace === void 0 ? {} : { trace: e.trace }
822
+ });
823
+ n(this, "source");
824
+ n(this, "args");
825
+ n(this, "apply");
826
+ n(this, "unsubscribers", []);
827
+ n(this, "lastSuccessfulValue");
828
+ this.source = e.source, this.args = { ...e.args }, this.apply = e.apply, this.lastSuccessfulValue = void 0;
829
+ const s = [
830
+ this.source,
831
+ ...Object.values(this.args)
832
+ ];
833
+ this.unsubscribers = s.map((i) => i.subscribe(({ event: o }) => {
834
+ this.recompute(o);
835
+ }, { emitCurrent: !1 })), this.recompute(null, !1);
836
+ }
837
+ dispose() {
838
+ if (!this.isDisposed) {
839
+ for (const e of this.unsubscribers) e();
840
+ this.unsubscribers = [], super.dispose();
841
+ }
842
+ }
843
+ recompute(e, s = !0) {
844
+ var p;
845
+ const i = [
846
+ this.source,
847
+ ...Object.values(this.args)
848
+ ], o = ((p = i.find((l) => l.getError() != null)) == null ? void 0 : p.getError()) ?? null;
849
+ let u = j(
850
+ i.map((l) => l.getFetchState())
851
+ );
852
+ const a = this.source.get();
853
+ let c = this.lastSuccessfulValue, f = o;
854
+ try {
855
+ const l = Object.fromEntries(
856
+ Object.entries(this.args).map(([d, v]) => [d, v.get()])
857
+ );
858
+ c = this.apply(a, l), this.lastSuccessfulValue = c;
859
+ } catch (l) {
860
+ f = l, u = h.Error;
861
+ }
862
+ if (o != null && (f = o, u = h.Error), !s) {
863
+ this.value = c, this.fetchState = u, this.error = f;
864
+ return;
865
+ }
866
+ this.setSnapshot({
867
+ value: c,
868
+ fetchState: u,
869
+ error: f,
870
+ cause: "derived endpoint source changed",
871
+ parentEvent: e
872
+ });
873
+ }
874
+ }
875
+ function E(t, r = "Endpoint query options") {
876
+ if (t == null || typeof t != "object" || Array.isArray(t))
877
+ throw new TypeError(`${r} must be an object`);
878
+ }
879
+ function A(t) {
880
+ if (t == null || typeof t != "object" || Array.isArray(t))
881
+ throw new TypeError("Endpoint args must be a named record of emitters");
882
+ for (const [r, e] of Object.entries(t))
883
+ if (!z(e))
884
+ throw new TypeError(`Endpoint argument ${r} must be an emitter`);
885
+ }
886
+ function z(t) {
887
+ return t != null && (typeof t == "object" || typeof t == "function") && typeof Reflect.get(t, "get") == "function" && typeof Reflect.get(t, "getFetchState") == "function" && typeof Reflect.get(t, "getError") == "function" && typeof Reflect.get(t, "subscribe") == "function";
888
+ }
248
889
  export {
249
- w as BaseEmitter,
250
- _ as DerivedEmitter,
251
- E as Emitter,
252
- y as EventBubble,
253
- b as EventBus,
254
- p as FetchState,
255
- x as FetchStateValues,
256
- H as LiveQuery,
257
- z as QueryArg,
258
- T as QueryHandler,
259
- I as RestQueryHandler,
260
- D as combineFetchStates
890
+ fe as AsyncCommand,
891
+ M as AsyncCommandConcurrencyError,
892
+ g as BaseEmitter,
893
+ D as DerivedEmitter,
894
+ le as DerivedEndpoint,
895
+ ae as DerivedLiveResult,
896
+ U as Emitter,
897
+ b as EventBubble,
898
+ w as EventBus,
899
+ h as FetchState,
900
+ S as FetchStateValues,
901
+ I as LiveQuery,
902
+ pe as QueryArg,
903
+ ue as QueryEndpoint,
904
+ ee as QueryHandler,
905
+ ce as RestEndpoint,
906
+ re as RestQueryHandler,
907
+ j as combineFetchStates,
908
+ ye as derivedEndpoint,
909
+ de as queryEndpoint,
910
+ be as restEndpoint
261
911
  };
262
912
  //# sourceMappingURL=index.js.map