simply-observe 1.0.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 ADDED
@@ -0,0 +1,703 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all2) => {
6
+ for (var name in all2)
7
+ __defProp(target, name, { get: all2[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var src_exports = {};
21
+ __export(src_exports, {
22
+ Observer: () => Observer,
23
+ ObserverLike: () => ObserverLike,
24
+ Subject: () => Subject,
25
+ all: () => all,
26
+ catchError: () => catchError,
27
+ debounce: () => debounce,
28
+ filter: () => filter,
29
+ flat: () => flat,
30
+ interval: () => interval,
31
+ latest: () => latest,
32
+ map: () => map,
33
+ of: () => of,
34
+ partial: () => partial,
35
+ race: () => race,
36
+ retry: () => retry,
37
+ sequent: () => sequent,
38
+ skip: () => skip,
39
+ take: () => take,
40
+ takeUntil: () => takeUntil,
41
+ tap: () => tap,
42
+ timeout: () => timeout,
43
+ toPipe: () => toPipe,
44
+ zip: () => zip
45
+ });
46
+ module.exports = __toCommonJS(src_exports);
47
+
48
+ // src/subscription.ts
49
+ var Subscription = class Subscription2 {
50
+ constructor(_unsubscribe = () => true) {
51
+ this._unsubscribe = _unsubscribe;
52
+ this._ref = crypto.randomUUID();
53
+ this._linked = [];
54
+ this._parents = null;
55
+ this._closed = false;
56
+ this.unsubscribe = () => {
57
+ let error;
58
+ if (!this._closed) {
59
+ this._closed = true;
60
+ const parents = this._parents;
61
+ this._parents = null;
62
+ if (parents) {
63
+ for (let parent of parents) {
64
+ parent.remove(this);
65
+ }
66
+ }
67
+ try {
68
+ if (!this._unsubscribe()) throw Error("Error occurred during unsubscription");
69
+ } catch (err) {
70
+ error = err;
71
+ }
72
+ const linked = this._linked;
73
+ this._linked = [];
74
+ for (let subscription of linked) {
75
+ subscription.unsubscribe();
76
+ }
77
+ }
78
+ if (error) throw error;
79
+ };
80
+ this.add = (subscription) => {
81
+ if (subscription !== this) {
82
+ if (this._closed) subscription.unsubscribe();
83
+ else {
84
+ if (subscription.closed || subscription.hasParent(this)) return;
85
+ subscription.linkParent(this);
86
+ this._linked.push(subscription);
87
+ }
88
+ }
89
+ };
90
+ this.remove = (subscription) => {
91
+ if (subscription !== this) {
92
+ const index = this._linked.indexOf(subscription);
93
+ 0 <= index && this._linked.splice(index, 1);
94
+ if (subscription.hasParent(this)) subscription.removeParent(this);
95
+ }
96
+ };
97
+ this.linkParent = (subscription) => {
98
+ if (!this._parents) this._parents = [];
99
+ if (this.hasParent(subscription)) return;
100
+ this._parents.push(subscription);
101
+ };
102
+ this.removeParent = (subscription) => {
103
+ if (!Array.isArray(this._parents)) return;
104
+ const index = this._parents.indexOf(subscription);
105
+ 0 <= index && this._parents.splice(index, 1);
106
+ if (this._parents.length === 0) this._parents = null;
107
+ };
108
+ this.hasParent = (subscription) => {
109
+ var _a;
110
+ return (_a = this._parents) == null ? void 0 : _a.includes(subscription);
111
+ };
112
+ }
113
+ get ref() {
114
+ return this._ref;
115
+ }
116
+ get closed() {
117
+ return this._closed;
118
+ }
119
+ get parents() {
120
+ return this._parents;
121
+ }
122
+ };
123
+ var subscription_default = Subscription;
124
+
125
+ // src/context.ts
126
+ var ObserverContext = class ObserverContext2 {
127
+ constructor() {
128
+ this._invoked = false;
129
+ this._closed = false;
130
+ this._subscribers = /* @__PURE__ */ new Set();
131
+ this.update = (value) => {
132
+ if (!this.active) return;
133
+ for (let { next } of this._subscribers.values()) {
134
+ if (next || typeof next === "function") {
135
+ try {
136
+ next(value);
137
+ } catch (error) {
138
+ this.error(error);
139
+ }
140
+ }
141
+ }
142
+ };
143
+ this.error = (value) => {
144
+ if (!this.active) return;
145
+ this._closed = true;
146
+ const subscribers = [...this._subscribers.values()];
147
+ this._subscribers.clear();
148
+ for (let { error } of subscribers) {
149
+ if (error || typeof error === "function") {
150
+ error(value);
151
+ }
152
+ }
153
+ this.finalize();
154
+ };
155
+ this.complete = (final) => {
156
+ if (!this.active) return;
157
+ this._closed = true;
158
+ const subscribers = [...this._subscribers.values()];
159
+ this._subscribers.clear();
160
+ for (let { complete } of subscribers) {
161
+ if (complete || typeof complete === "function") {
162
+ complete(final);
163
+ }
164
+ }
165
+ this.finalize();
166
+ };
167
+ }
168
+ get active() {
169
+ return !this._closed;
170
+ }
171
+ get invoked() {
172
+ return this._invoked;
173
+ }
174
+ finalize() {
175
+ if (this._teardown && typeof this._teardown === "function") {
176
+ this._teardown();
177
+ }
178
+ }
179
+ add(subscriber) {
180
+ this._subscribers.add(subscriber);
181
+ return () => {
182
+ this._subscribers.delete(subscriber);
183
+ if (this._subscribers.size === 0) {
184
+ this.close();
185
+ }
186
+ return true;
187
+ };
188
+ }
189
+ invoke(task) {
190
+ this._invoked = true;
191
+ this._teardown = task(this.update, this.error, this.complete);
192
+ }
193
+ close() {
194
+ if (!this.active) return;
195
+ this._closed = true;
196
+ this._subscribers.clear();
197
+ this.finalize();
198
+ }
199
+ };
200
+
201
+ // src/pipes.ts
202
+ function map(fn) {
203
+ return (source) => new Observer((next, error, complete) => {
204
+ const sub = source.subscribe(
205
+ (val) => next(fn(val)),
206
+ error,
207
+ complete
208
+ );
209
+ return () => sub.unsubscribe();
210
+ });
211
+ }
212
+ function filter(predicate) {
213
+ return (source) => new Observer((next, error, complete) => {
214
+ const sub = source.subscribe(
215
+ (val) => {
216
+ if (predicate(val)) next(val);
217
+ },
218
+ error,
219
+ complete
220
+ );
221
+ return () => sub.unsubscribe();
222
+ });
223
+ }
224
+ function tap(fn) {
225
+ return (source) => new Observer((next, error, complete) => {
226
+ const sub = source.subscribe(
227
+ (val) => {
228
+ fn(val);
229
+ next(val);
230
+ },
231
+ error,
232
+ complete
233
+ );
234
+ return () => sub.unsubscribe();
235
+ });
236
+ }
237
+ function catchError(handler) {
238
+ return (source) => new Observer((next, error, complete) => {
239
+ let inner = null;
240
+ const outerSub = source.subscribe(
241
+ next,
242
+ (err) => {
243
+ const fallback = handler(err);
244
+ inner = fallback.subscribe(next, error, complete);
245
+ },
246
+ complete
247
+ );
248
+ return () => {
249
+ outerSub.unsubscribe();
250
+ inner == null ? void 0 : inner.unsubscribe();
251
+ };
252
+ });
253
+ }
254
+ function retry(count) {
255
+ return (source) => new Observer((next, error, complete) => {
256
+ const onError = (err) => {
257
+ if (count <= 0) {
258
+ error(err);
259
+ return;
260
+ }
261
+ count--;
262
+ inner = source.subscribe(next, onError, complete);
263
+ };
264
+ let inner = null;
265
+ const outerSub = source.subscribe(
266
+ next,
267
+ onError,
268
+ complete
269
+ );
270
+ return () => {
271
+ outerSub.unsubscribe();
272
+ inner == null ? void 0 : inner.unsubscribe();
273
+ };
274
+ });
275
+ }
276
+ function take(count) {
277
+ return (source) => new Observer((next, error, complete) => {
278
+ const sub = source.subscribe(
279
+ (val) => {
280
+ if (count < 0) return;
281
+ if (count === 0) complete();
282
+ count--;
283
+ next(val);
284
+ },
285
+ error,
286
+ complete
287
+ );
288
+ return () => sub.unsubscribe();
289
+ });
290
+ }
291
+ function takeUntil(notifier) {
292
+ return (source) => new Observer((next, error, complete) => {
293
+ const notification = notifier.subscribe(() => complete());
294
+ const sub = source.subscribe(
295
+ (val) => next(val),
296
+ error,
297
+ complete
298
+ );
299
+ return () => {
300
+ sub.unsubscribe();
301
+ notification.unsubscribe();
302
+ };
303
+ });
304
+ }
305
+ function skip(count) {
306
+ return (source) => new Observer((next, error, complete) => {
307
+ const sub = source.subscribe(
308
+ (val) => {
309
+ if (count > 0) {
310
+ count--;
311
+ return;
312
+ }
313
+ ;
314
+ next(val);
315
+ },
316
+ error,
317
+ complete
318
+ );
319
+ return () => sub.unsubscribe();
320
+ });
321
+ }
322
+ function debounce(value) {
323
+ return (source) => new Observer((next, error, complete) => {
324
+ let timeout2;
325
+ const sub = source.subscribe(
326
+ (val) => {
327
+ if (timeout2) clearTimeout(timeout2);
328
+ timeout2 = setTimeout(() => {
329
+ next(val);
330
+ }, value);
331
+ },
332
+ (err) => {
333
+ clearTimeout(timeout2);
334
+ error(err);
335
+ },
336
+ () => {
337
+ clearTimeout(timeout2);
338
+ complete();
339
+ }
340
+ );
341
+ return () => {
342
+ clearTimeout(timeout2);
343
+ sub.unsubscribe();
344
+ };
345
+ });
346
+ }
347
+ function toPipe(operators) {
348
+ if (operators.length === 0) return (x) => x;
349
+ if (operators.length === 1) return operators[0];
350
+ return (source) => {
351
+ return operators.reduce((a, f) => f(a), source);
352
+ };
353
+ }
354
+
355
+ // src/observer.ts
356
+ var ObserverLike = class {
357
+ constructor() {
358
+ this.ref = crypto.randomUUID();
359
+ this._context = new ObserverContext();
360
+ }
361
+ get closed() {
362
+ return !this._context.active;
363
+ }
364
+ };
365
+ var Observer = class Observer2 extends ObserverLike {
366
+ constructor(task) {
367
+ super();
368
+ this.task = task;
369
+ }
370
+ close() {
371
+ if (!this._context.active) return;
372
+ this._context.close();
373
+ }
374
+ subscribe(next, error, complete) {
375
+ if (!this._context.active) this._context = new ObserverContext();
376
+ const teardown = this._context.add({ next, error, complete });
377
+ if (!this._context.invoked) this._context.invoke(this.task);
378
+ return new Subscription(teardown);
379
+ }
380
+ pipe(...operators) {
381
+ return toPipe(operators)(this);
382
+ }
383
+ };
384
+
385
+ // src/subject.ts
386
+ var Subject = class Subject2 extends ObserverLike {
387
+ constructor(initial) {
388
+ super();
389
+ this.value = initial;
390
+ }
391
+ next(value) {
392
+ if (!this._context.active) return;
393
+ this.value = value;
394
+ this._context.update(value);
395
+ }
396
+ error(value) {
397
+ if (!this._context.active) return;
398
+ this.terminal = { type: "error", value };
399
+ this._context.error(value);
400
+ }
401
+ complete(final) {
402
+ if (!this._context.active) return;
403
+ this.terminal = { type: "complete", value: final };
404
+ this._context.complete(final);
405
+ }
406
+ close() {
407
+ if (!this._context.active) return;
408
+ this.terminal = { type: "complete", value: void 0 };
409
+ this._context.close();
410
+ }
411
+ asObservable() {
412
+ return new Observer((next, error, complete) => {
413
+ const sub = this.subscribe(next, error, complete);
414
+ return () => sub.unsubscribe();
415
+ });
416
+ }
417
+ subscribe(next, error, complete) {
418
+ if (this.terminal) {
419
+ if (this.terminal.type === "error") error == null ? void 0 : error(this.terminal.value);
420
+ else complete == null ? void 0 : complete(this.terminal.value);
421
+ return new Subscription(() => true);
422
+ }
423
+ const sub = new Subscription(this._context.add({ next, error, complete }));
424
+ if (this.value !== void 0) next(this.value);
425
+ return sub;
426
+ }
427
+ };
428
+
429
+ // src/utils.ts
430
+ function of(...args) {
431
+ return new Observer((next, _, complete) => {
432
+ for (let item of args) {
433
+ next(item);
434
+ }
435
+ complete();
436
+ });
437
+ }
438
+ function timeout(value, delay = 0) {
439
+ return new Observer((next, _, complete) => {
440
+ const t = setTimeout(() => {
441
+ next(value);
442
+ complete();
443
+ }, delay);
444
+ return () => clearTimeout(t);
445
+ });
446
+ }
447
+ function interval(delay = 0) {
448
+ return new Observer((next) => {
449
+ let count = 0;
450
+ const t = setInterval(() => next(count++), delay);
451
+ return () => clearInterval(t);
452
+ });
453
+ }
454
+ function all(observers) {
455
+ const task = (next, error, complete) => {
456
+ if (observers.length === 0) {
457
+ next([]);
458
+ complete();
459
+ return () => {
460
+ };
461
+ }
462
+ const root = new subscription_default();
463
+ const stream = Array(observers.length);
464
+ const completed = Array(observers.length).fill(false);
465
+ observers.forEach((obs, i) => {
466
+ const sub = obs.subscribe((val) => {
467
+ stream[i] = val;
468
+ }, (err) => {
469
+ root.unsubscribe();
470
+ error(err);
471
+ }, () => {
472
+ completed[i] = true;
473
+ if (isAllCompleted(completed)) {
474
+ root.unsubscribe();
475
+ next([...stream]);
476
+ complete();
477
+ }
478
+ });
479
+ root.add(sub);
480
+ });
481
+ return () => root.unsubscribe();
482
+ };
483
+ return new Observer(task);
484
+ }
485
+ function partial(observers) {
486
+ const task = (next, error, complete) => {
487
+ if (observers.length === 0) {
488
+ complete();
489
+ return () => {
490
+ };
491
+ }
492
+ const root = new subscription_default();
493
+ const stream = Array(observers.length);
494
+ const completed = Array(observers.length).fill(false);
495
+ observers.map((obs, i) => {
496
+ const sub = obs.subscribe((val) => {
497
+ stream[i] = val;
498
+ }, (err) => {
499
+ root.unsubscribe();
500
+ error(err);
501
+ }, () => {
502
+ completed[i] = true;
503
+ next([...stream]);
504
+ if (isAllCompleted(completed)) {
505
+ root.unsubscribe();
506
+ complete();
507
+ }
508
+ ;
509
+ });
510
+ root.add(sub);
511
+ });
512
+ return () => root.unsubscribe();
513
+ };
514
+ return new Observer(task);
515
+ }
516
+ function latest(observers) {
517
+ const task = (next, error, complete) => {
518
+ if (observers.length === 0) {
519
+ next([]);
520
+ complete();
521
+ return () => {
522
+ };
523
+ }
524
+ const root = new subscription_default();
525
+ const stream = Array(observers.length);
526
+ const completed = Array(observers.length).fill(false);
527
+ observers.forEach((obs, i) => {
528
+ const sub = obs.subscribe((val) => {
529
+ stream[i] = val;
530
+ next([...stream]);
531
+ }, (err) => {
532
+ root.unsubscribe();
533
+ error(err);
534
+ }, () => {
535
+ completed[i] = true;
536
+ if (isAllCompleted(completed)) {
537
+ root.unsubscribe();
538
+ complete();
539
+ }
540
+ });
541
+ root.add(sub);
542
+ });
543
+ return () => root.unsubscribe();
544
+ };
545
+ return new Observer(task);
546
+ }
547
+ function sequent(observers) {
548
+ const task = (next, error, complete) => {
549
+ if (observers.length === 0) {
550
+ complete();
551
+ return () => {
552
+ };
553
+ }
554
+ const root = new subscription_default();
555
+ const queue = [...observers];
556
+ const mountNext = () => {
557
+ let value;
558
+ let obs = queue.shift();
559
+ if (!obs) {
560
+ root.unsubscribe();
561
+ complete();
562
+ return;
563
+ }
564
+ const sub = obs.subscribe((val) => {
565
+ value = val;
566
+ next(value);
567
+ }, (err) => {
568
+ root.unsubscribe();
569
+ error(err);
570
+ }, () => {
571
+ mountNext();
572
+ });
573
+ root.add(sub);
574
+ };
575
+ mountNext();
576
+ return () => root.unsubscribe();
577
+ };
578
+ return new Observer(task);
579
+ }
580
+ function race(observers) {
581
+ const task = (next, error, complete) => {
582
+ if (observers.length === 0) {
583
+ complete();
584
+ return () => {
585
+ };
586
+ }
587
+ const root = new subscription_default();
588
+ let won = false;
589
+ observers.forEach((obs) => {
590
+ const sub = obs.subscribe((val) => {
591
+ if (won) return;
592
+ won = true;
593
+ root.unsubscribe();
594
+ next(val);
595
+ complete();
596
+ }, (err) => {
597
+ if (won) return;
598
+ won = true;
599
+ root.unsubscribe();
600
+ error(err);
601
+ }, () => {
602
+ });
603
+ root.add(sub);
604
+ });
605
+ return () => root.unsubscribe();
606
+ };
607
+ return new Observer(task);
608
+ }
609
+ function flat(observers) {
610
+ const task = (next, error, complete) => {
611
+ if (observers.length === 0) {
612
+ complete();
613
+ return () => {
614
+ };
615
+ }
616
+ const root = new subscription_default();
617
+ const completed = Array(observers.length).fill(false);
618
+ observers.forEach((obs, i) => {
619
+ const sub = obs.subscribe((val) => {
620
+ next(val);
621
+ }, (err) => {
622
+ root.unsubscribe();
623
+ error(err);
624
+ }, () => {
625
+ completed[i] = true;
626
+ if (isAllCompleted(completed)) {
627
+ root.unsubscribe();
628
+ complete();
629
+ }
630
+ });
631
+ root.add(sub);
632
+ });
633
+ return () => root.unsubscribe();
634
+ };
635
+ return new Observer(task);
636
+ }
637
+ function zip(observers) {
638
+ const task = (next, error, complete) => {
639
+ if (observers.length === 0) {
640
+ next([]);
641
+ complete();
642
+ return () => {
643
+ };
644
+ }
645
+ const root = new subscription_default();
646
+ const streams = observers.map(() => []);
647
+ const completed = Array(observers.length).fill(false);
648
+ const checkReady = () => {
649
+ const min = Math.min(...streams.map((s) => s.length));
650
+ if (min > 0) {
651
+ next(streams.map((stream) => stream.shift()));
652
+ }
653
+ };
654
+ observers.forEach((obs, i) => {
655
+ const sub = obs.subscribe((val) => {
656
+ streams[i].push(val);
657
+ checkReady();
658
+ }, (err) => {
659
+ root.unsubscribe();
660
+ error(err);
661
+ }, () => {
662
+ completed[i] = true;
663
+ if (isAllCompleted(completed)) {
664
+ root.unsubscribe();
665
+ complete();
666
+ }
667
+ });
668
+ root.add(sub);
669
+ });
670
+ return () => root.unsubscribe();
671
+ };
672
+ return new Observer(task);
673
+ }
674
+ var isAllCompleted = (completed) => {
675
+ return !completed.includes(false);
676
+ };
677
+ // Annotate the CommonJS export names for ESM import in node:
678
+ 0 && (module.exports = {
679
+ Observer,
680
+ ObserverLike,
681
+ Subject,
682
+ all,
683
+ catchError,
684
+ debounce,
685
+ filter,
686
+ flat,
687
+ interval,
688
+ latest,
689
+ map,
690
+ of,
691
+ partial,
692
+ race,
693
+ retry,
694
+ sequent,
695
+ skip,
696
+ take,
697
+ takeUntil,
698
+ tap,
699
+ timeout,
700
+ toPipe,
701
+ zip
702
+ });
703
+ //# sourceMappingURL=index.js.map