@adviser/cement 0.4.23 → 0.4.25

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.
Files changed (78) hide show
  1. package/cjs/future.cjs +1 -1
  2. package/cjs/future.cjs.map +1 -1
  3. package/cjs/future.d.ts.map +1 -1
  4. package/cjs/is-promise.cjs +4 -0
  5. package/cjs/is-promise.cjs.map +1 -1
  6. package/cjs/is-promise.d.ts +2 -0
  7. package/cjs/is-promise.d.ts.map +1 -1
  8. package/cjs/option.cjs +3 -0
  9. package/cjs/option.cjs.map +1 -1
  10. package/cjs/option.d.ts +1 -0
  11. package/cjs/option.d.ts.map +1 -1
  12. package/cjs/resolve-once.cjs +265 -93
  13. package/cjs/resolve-once.cjs.map +1 -1
  14. package/cjs/resolve-once.d.ts +48 -18
  15. package/cjs/resolve-once.d.ts.map +1 -1
  16. package/cjs/resolve-once.test.cjs +115 -9
  17. package/cjs/resolve-once.test.cjs.map +1 -1
  18. package/cjs/version.cjs +1 -1
  19. package/deno.json +1 -1
  20. package/esm/future.d.ts.map +1 -1
  21. package/esm/future.js +1 -1
  22. package/esm/future.js.map +1 -1
  23. package/esm/is-promise.d.ts +2 -0
  24. package/esm/is-promise.d.ts.map +1 -1
  25. package/esm/is-promise.js +3 -0
  26. package/esm/is-promise.js.map +1 -1
  27. package/esm/option.d.ts +1 -0
  28. package/esm/option.d.ts.map +1 -1
  29. package/esm/option.js +3 -0
  30. package/esm/option.js.map +1 -1
  31. package/esm/resolve-once.d.ts +48 -18
  32. package/esm/resolve-once.d.ts.map +1 -1
  33. package/esm/resolve-once.js +262 -92
  34. package/esm/resolve-once.js.map +1 -1
  35. package/esm/resolve-once.test.js +116 -10
  36. package/esm/resolve-once.test.js.map +1 -1
  37. package/esm/version.js +1 -1
  38. package/package.json +3 -3
  39. package/src/future.ts +2 -1
  40. package/src/is-promise.ts +6 -0
  41. package/src/option.ts +4 -0
  42. package/src/resolve-once.ts +342 -114
  43. package/ts/cjs/future.d.ts.map +1 -1
  44. package/ts/cjs/future.js +1 -1
  45. package/ts/cjs/future.js.map +1 -1
  46. package/ts/cjs/is-promise.d.ts +2 -0
  47. package/ts/cjs/is-promise.d.ts.map +1 -1
  48. package/ts/cjs/is-promise.js +4 -0
  49. package/ts/cjs/is-promise.js.map +1 -1
  50. package/ts/cjs/option.d.ts +1 -0
  51. package/ts/cjs/option.d.ts.map +1 -1
  52. package/ts/cjs/option.js +3 -0
  53. package/ts/cjs/option.js.map +1 -1
  54. package/ts/cjs/resolve-once.d.ts +48 -18
  55. package/ts/cjs/resolve-once.d.ts.map +1 -1
  56. package/ts/cjs/resolve-once.js +265 -93
  57. package/ts/cjs/resolve-once.js.map +1 -1
  58. package/ts/cjs/resolve-once.test.js +115 -9
  59. package/ts/cjs/resolve-once.test.js.map +1 -1
  60. package/ts/cjs/version.js +1 -1
  61. package/ts/esm/future.d.ts.map +1 -1
  62. package/ts/esm/future.js +1 -1
  63. package/ts/esm/future.js.map +1 -1
  64. package/ts/esm/is-promise.d.ts +2 -0
  65. package/ts/esm/is-promise.d.ts.map +1 -1
  66. package/ts/esm/is-promise.js +3 -0
  67. package/ts/esm/is-promise.js.map +1 -1
  68. package/ts/esm/option.d.ts +1 -0
  69. package/ts/esm/option.d.ts.map +1 -1
  70. package/ts/esm/option.js +3 -0
  71. package/ts/esm/option.js.map +1 -1
  72. package/ts/esm/resolve-once.d.ts +48 -18
  73. package/ts/esm/resolve-once.d.ts.map +1 -1
  74. package/ts/esm/resolve-once.js +262 -92
  75. package/ts/esm/resolve-once.js.map +1 -1
  76. package/ts/esm/resolve-once.test.js +116 -10
  77. package/ts/esm/resolve-once.test.js.map +1 -1
  78. package/ts/esm/version.js +1 -1
@@ -1,11 +1,13 @@
1
1
  import { Future } from "./future.js";
2
- import { isPromise } from "./is-promise.js";
2
+ import { UnPromisify } from "./is-promise.js";
3
+ import { isPromise, Promisable } from "./is-promise.js";
3
4
  import { LRUMap, LRUParam, UnregFn } from "./lru-map-set.js";
4
5
  import { Result } from "./result.js";
6
+ import { Option } from "./option.js";
5
7
 
6
- interface ResolveSeqItem<T, C> {
8
+ interface ResolveSeqItem<T, C, R extends Promisable<T>> {
7
9
  readonly future: Future<T>;
8
- readonly fn: (c?: C) => Promise<T>;
10
+ readonly fn: (c?: C) => R;
9
11
  readonly id?: number;
10
12
  }
11
13
 
@@ -27,145 +29,363 @@ export class ResolveSeq<T, C = void> {
27
29
  }
28
30
  return Promise.resolve();
29
31
  }
30
- _step(item?: ResolveSeqItem<T, C>): Promise<void> {
32
+ async _step<R extends Promisable<T>>(item?: ResolveSeqItem<T, C, R>): Promise<void> {
31
33
  if (!item) {
32
34
  // done
33
35
  this._flushWaiting.forEach((f) => f.resolve());
34
36
  this._flushWaiting?.splice(0, this._flushWaiting.length);
35
37
  return Promise.resolve();
36
38
  }
37
- item
38
- .fn(this.ctx)
39
- .then((value) => item.future.resolve(value))
40
- .catch((e) => item.future.reject(e as Error))
41
- .finally(() => {
42
- this._seqFutures.shift();
43
- void this._step(this._seqFutures[0]);
44
- });
45
- return Promise.resolve();
39
+ let value;
40
+ try {
41
+ const promiseOrValue = item.fn(this.ctx);
42
+ if (isPromise(promiseOrValue)) {
43
+ value = await promiseOrValue;
44
+ } else {
45
+ value = promiseOrValue;
46
+ }
47
+ item.future.resolve(value as T);
48
+ } catch (e) {
49
+ item.future.reject(e as Error);
50
+ } finally {
51
+ this._seqFutures.shift();
52
+ }
53
+ return this._step(this._seqFutures[0]);
46
54
  }
47
- readonly _seqFutures: ResolveSeqItem<T, C>[] = [];
48
- async add(fn: (c?: C) => Promise<T>, id?: number): Promise<T> {
55
+ readonly _seqFutures: ResolveSeqItem<T, C, Promisable<T>>[] = [];
56
+ add<R extends Promisable<T>>(fn: (c?: C) => R, id?: number): Promise<UnPromisify<R>> {
49
57
  const future = new Future<T>();
50
58
  this._seqFutures.push({ future, fn, id });
51
59
  if (this._seqFutures.length === 1) {
52
- void this._step(this._seqFutures[0]);
60
+ void this._step(this._seqFutures[0]); // exit into eventloop
53
61
  }
54
- return future.asPromise();
62
+ return future.asPromise() as Promise<UnPromisify<R>>;
55
63
  }
56
64
  }
57
65
 
58
- export class ResolveOnce<T, CTX = void> {
59
- _onceDone = false;
60
- readonly _onceFutures: Future<T>[] = [];
61
- _onceOk = false;
62
- _onceValue?: T;
63
- _onceError?: Error;
64
- _isPromise = false;
65
- _inProgress?: Future<T>;
66
+ // readonly _onceFutures: Future<T>[] = [];
67
+ // _onceDone = false;
68
+ // _onceOk = false;
69
+ // _onceValue?: T;
70
+ // _onceError?: Error;
71
+ // _isPromise = false;
72
+ // _inProgress?: Future<T>;
66
73
 
67
- readonly ctx?: CTX;
74
+ // ResolveOnce
75
+ // cases SyncMode, AsyncMode
68
76
 
69
- constructor(ctx?: CTX) {
70
- this.ctx = ctx;
77
+ type ResolveState = "initial" | "processed" | "waiting" | "processing";
78
+
79
+ interface ResolveOnceIf<T extends Promisable<unknown>, CTX = void> {
80
+ get ready(): boolean;
81
+ get value(): UnPromisify<T> | undefined;
82
+ get error(): Error | undefined;
83
+ get state(): ResolveState;
84
+
85
+ once<R extends Promisable<UnPromisify<T>>>(fn: (c?: CTX) => R): R;
86
+ reset<R extends Promisable<UnPromisify<T>>>(fn?: (c?: CTX) => R): R;
87
+ }
88
+
89
+ export class SyncResolveOnce<T extends Promisable<unknown>, CTX = void> {
90
+ state: ResolveState = "initial";
91
+
92
+ #value?: T;
93
+ #error?: Error;
94
+
95
+ readonly queueLength = 0;
96
+
97
+ get value(): T | undefined {
98
+ return this.#value;
99
+ }
100
+
101
+ get error(): Error | undefined {
102
+ return this.#error;
71
103
  }
72
104
 
73
105
  get ready(): boolean {
74
- return this._onceDone;
106
+ return this.state === "processed";
75
107
  }
76
108
 
77
- get value(): T | undefined {
78
- return this._onceDone ? this._onceValue : undefined;
109
+ readonly #ctx?: CTX;
110
+ constructor(ctx?: CTX) {
111
+ this.#ctx = ctx;
79
112
  }
80
113
 
81
- reset(): void {
82
- this._onceDone = false;
83
- this._onceOk = false;
84
- this._onceValue = undefined;
85
- this._onceError = undefined;
86
- if (this._inProgress) {
87
- const idx = this._onceFutures.findIndex((f) => f === this._inProgress);
88
- if (idx >= 0) {
89
- // leave the current in progress future
90
- this._onceFutures.push(...this._onceFutures.splice(2).slice(1));
114
+ resolve(fn: (ctx?: CTX) => T): T {
115
+ if (this.state === "initial") {
116
+ this.state = "processed";
117
+ try {
118
+ this.#value = fn(this.#ctx);
119
+ } catch (e) {
120
+ this.#error = e as Error;
91
121
  }
92
- } else {
93
- this._onceFutures.length = 0;
122
+ if (isPromise(this.value)) {
123
+ throw new Error("SyncResolveOnce.once fn returned a promise");
124
+ }
125
+ }
126
+ if (this.#error) {
127
+ throw this.#error;
94
128
  }
129
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
130
+ return this.#value as T;
95
131
  }
96
132
 
97
- // T extends Option<infer U> ? U : T
98
- once<R>(fn: (c?: CTX) => R): R {
99
- if (this._onceDone) {
100
- if (this._onceError) {
101
- if (this._isPromise) {
102
- return Promise.reject(this._onceError) as unknown as R;
103
- } else {
104
- throw this._onceError;
105
- }
106
- }
107
- if (this._onceOk) {
108
- if (this._isPromise) {
109
- return Promise.resolve(this._onceValue) as unknown as R;
133
+ reset(fn?: (c?: CTX) => T): T | undefined {
134
+ this.state = "initial";
135
+ this.#value = undefined;
136
+ this.#error = undefined;
137
+ if (fn) {
138
+ return this.resolve(fn);
139
+ }
140
+ return undefined as T;
141
+ }
142
+ }
143
+
144
+ class AsyncResolveItem<T extends Promisable<unknown>> {
145
+ readonly id = Math.random();
146
+ #state: ResolveState = "initial";
147
+ readonly #toResolve: Promise<UnPromisify<T>>;
148
+ #value: Option<UnPromisify<T>> = Option.None();
149
+ #error?: Error;
150
+
151
+ constructor(fn: Promise<UnPromisify<T>>) {
152
+ this.#toResolve = fn;
153
+ }
154
+
155
+ get value(): UnPromisify<T> | undefined {
156
+ return this.#value.IsSome() ? this.#value.unwrap() : undefined;
157
+ }
158
+
159
+ get error(): Error | undefined {
160
+ return this.#error;
161
+ }
162
+
163
+ readonly #queue: Future<UnPromisify<T>>[] = [];
164
+
165
+ get queuelength(): number {
166
+ return this.#queue.length;
167
+ }
168
+
169
+ isDisposable(): boolean {
170
+ return this.#state === "processed" && this.#queue.length === 0;
171
+ }
172
+
173
+ #resolveFuture(future?: Future<UnPromisify<T>>): void {
174
+ if (!future) {
175
+ return;
176
+ }
177
+ if (this.#error) {
178
+ future.reject(this.#error);
179
+ return;
180
+ }
181
+ if (this.#value.IsSome()) {
182
+ future.resolve(this.#value.Unwrap());
183
+ }
184
+ }
185
+
186
+ #promiseResult(): Promise<UnPromisify<T>> {
187
+ if (this.#error) {
188
+ return Promise.reject(this.#error);
189
+ }
190
+ if (this.#value.IsSome()) {
191
+ return Promise.resolve(this.#value.Unwrap());
192
+ }
193
+ throw new Error("AsyncResolveItem.#promiseResult impossible");
194
+ }
195
+
196
+ resolve(): T {
197
+ if (this.#state === "initial") {
198
+ this.#state = "waiting";
199
+ const future = new Future<UnPromisify<T>>();
200
+ // console.log("asyncItem addQueue#initial", this.id, this.#queue.length);
201
+ this.#queue.push(future);
202
+ this.#toResolve
203
+ .then((value) => {
204
+ this.#value = Option.Some(value);
205
+ })
206
+ .catch((e) => {
207
+ this.#error = e as Error;
208
+ })
209
+ .finally(() => {
210
+ this.#state = "processed";
211
+ while (this.#queue.length > 0) {
212
+ this.#resolveFuture(this.#queue.shift());
213
+ }
214
+ });
215
+ return future.asPromise() as T;
216
+ }
217
+ if (this.#state === "processed") {
218
+ return this.#promiseResult() as T;
219
+ }
220
+ if (this.#state === "waiting") {
221
+ const future = new Future<UnPromisify<T>>();
222
+ // console.log("asyncItem addQueue#waiting", this.id, this.#queue.length);
223
+ this.#queue.push(future);
224
+ return future.asPromise() as T;
225
+ }
226
+ throw new Error("AsyncResolveItem.resolve impossible");
227
+ }
228
+ }
229
+
230
+ export class AsyncResolveOnce<T extends Promisable<unknown>, CTX = void> {
231
+ // readonly id = Math.random();
232
+ state: ResolveState = "initial";
233
+
234
+ readonly #queue: AsyncResolveItem<T>[] = [];
235
+
236
+ readonly #ctx?: CTX;
237
+ constructor(ctx?: CTX) {
238
+ this.#ctx = ctx;
239
+ }
240
+
241
+ #active(): AsyncResolveItem<T> {
242
+ const r = this.#queue[this.#queue.length - 1];
243
+ if (!r) {
244
+ throw new Error("AsyncResolveOnce.#active impossible");
245
+ }
246
+ return r;
247
+ }
248
+
249
+ get queueLength(): number {
250
+ return this.#queue.reduce((acc, r) => acc + r.queuelength, this.#queue.length);
251
+ }
252
+
253
+ get ready(): boolean {
254
+ return this.state !== "initial";
255
+ }
256
+ get value(): UnPromisify<T> | undefined {
257
+ if (this.state === "initial") {
258
+ return undefined;
259
+ }
260
+ return this.#active().value;
261
+ }
262
+
263
+ get error(): Error | undefined {
264
+ if (this.state === "initial") {
265
+ return undefined;
266
+ }
267
+ return this.#active().error;
268
+ }
269
+
270
+ resolve(fn: (ctx?: CTX) => T): T {
271
+ if (this.state === "initial") {
272
+ this.state = "waiting";
273
+ let promiseResult: Promise<UnPromisify<T>>;
274
+ try {
275
+ const couldBePromise = fn(this.#ctx);
276
+ if (!isPromise(couldBePromise)) {
277
+ promiseResult = Promise.resolve(couldBePromise as UnPromisify<T>);
110
278
  } else {
111
- return this._onceValue as unknown as R;
279
+ promiseResult = couldBePromise as Promise<UnPromisify<T>>;
112
280
  }
281
+ } catch (e) {
282
+ promiseResult = Promise.reject(e as Error);
113
283
  }
114
- throw new Error("ResolveOnce.once impossible");
284
+ // console.log("asyncOnce addQueue#initial", this.id, this.#queue.length);
285
+ this.#queue.push(new AsyncResolveItem(promiseResult));
115
286
  }
116
- const future = new Future<T>();
117
- this._onceFutures.push(future);
118
- if (this._onceFutures.length === 1) {
119
- const okFn = (value: T): void => {
120
- this._onceValue = value;
121
- this._onceOk = true;
122
- this._onceDone = true;
123
- if (this._isPromise) {
124
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
125
- this._onceFutures.forEach((f) => f.resolve(this._onceValue!));
126
- }
127
- this._onceFutures.length = 0;
128
- };
129
- const catchFn = (e: Error): void => {
130
- this._onceError = e;
131
- this._onceOk = false;
132
- this._onceValue = undefined;
133
- this._onceDone = true;
134
- if (this._isPromise) {
135
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
136
- this._onceFutures.forEach((f) => f.reject(this._onceError!));
137
- }
138
- this._onceFutures.length = 0;
139
- };
140
- this._inProgress = future;
141
- // let inCriticalSection = false;
287
+ // remove all disposable items
288
+ this.#queue
289
+ .slice(0, -1)
290
+ .map((i, idx) => (i.isDisposable() ? idx : undefined))
291
+ .filter((i) => i !== undefined)
292
+ .reverse()
293
+ .forEach((idx) => this.#queue.splice(idx, 1));
294
+
295
+ return this.#active().resolve();
296
+ }
297
+
298
+ reset(fn?: (c?: CTX) => T): T {
299
+ this.state = "initial";
300
+ if (fn) {
301
+ return this.resolve(fn);
302
+ }
303
+ return undefined as T;
304
+ }
305
+ }
306
+
307
+ export class ResolveOnce<T extends Promisable<unknown>, CTX = void> implements ResolveOnceIf<T, CTX> {
308
+ #state: ResolveState = "initial";
309
+
310
+ #syncOrAsync: Option<SyncResolveOnce<never, CTX> | AsyncResolveOnce<never, CTX>> = Option.None();
311
+
312
+ readonly #ctx?: CTX;
313
+ constructor(ctx?: CTX) {
314
+ this.#ctx = ctx;
315
+ }
316
+
317
+ get ready(): boolean {
318
+ return this.#state !== "initial" && this.#syncOrAsync.Unwrap().ready;
319
+ }
320
+
321
+ get value(): UnPromisify<T> | undefined {
322
+ if (this.#state === "initial") {
323
+ return undefined;
324
+ }
325
+ return this.#syncOrAsync.Unwrap().value as UnPromisify<T>;
326
+ }
327
+
328
+ get queueLength(): number {
329
+ if (this.#state === "initial") {
330
+ return 0;
331
+ }
332
+ return this.#syncOrAsync.Unwrap().queueLength;
333
+ }
334
+
335
+ get error(): Error | undefined {
336
+ if (this.#state === "initial") {
337
+ return undefined;
338
+ }
339
+ return this.#syncOrAsync.Unwrap().error;
340
+ }
341
+
342
+ get state(): ResolveState {
343
+ if (this.#state === "initial") {
344
+ return "initial";
345
+ }
346
+ return this.#syncOrAsync.Unwrap().state;
347
+ }
348
+
349
+ once<R extends Promisable<UnPromisify<T>>>(fn: (c?: CTX) => R): R {
350
+ let resultFn: (ctx?: CTX) => R;
351
+ if (this.#state === "initial") {
352
+ this.#state = "processing";
142
353
  try {
143
- const ret = fn(this.ctx);
144
- if (isPromise(ret)) {
145
- this._isPromise = true;
146
- // inCriticalSection = true;
147
- (ret as Promise<T>)
148
- .then(okFn)
149
- .catch(catchFn)
150
- .finally(() => {
151
- this._inProgress = undefined;
152
- });
354
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
355
+ const isSyncOrAsync = fn(this.#ctx) as R;
356
+ if (isPromise(isSyncOrAsync)) {
357
+ this.#syncOrAsync = Option.Some(new AsyncResolveOnce<never, CTX>(this.#ctx));
153
358
  } else {
154
- okFn(ret as unknown as T);
359
+ this.#syncOrAsync = Option.Some(new SyncResolveOnce<never, CTX>(this.#ctx));
155
360
  }
361
+ resultFn = (): R => isSyncOrAsync;
156
362
  } catch (e) {
157
- catchFn(e as Error);
158
- }
159
- if (!this._isPromise) {
160
- this._inProgress = undefined;
363
+ this.#syncOrAsync = Option.Some(new SyncResolveOnce<never, CTX>(this.#ctx));
364
+ resultFn = (): R => {
365
+ throw e;
366
+ };
367
+ } finally {
368
+ this.#state = "processed";
161
369
  }
162
- }
163
- if (this._isPromise) {
164
- return future.asPromise() as unknown as R;
165
370
  } else {
166
- // abit funky but i don't want to impl the return just once
167
- return this.once(fn);
371
+ resultFn = fn;
372
+ }
373
+ if (!this.#syncOrAsync) {
374
+ throw new Error("ResolveOnce.once impossible");
168
375
  }
376
+ return this.#syncOrAsync.Unwrap().resolve(resultFn as (c?: CTX) => never) as R;
377
+ }
378
+
379
+ reset<R extends Promisable<UnPromisify<T>>>(fn?: (c?: CTX) => R): R {
380
+ if (this.#state === "initial") {
381
+ return this.once(fn as (c?: CTX) => R);
382
+ }
383
+ if (this.#state === "processing") {
384
+ // eslint-disable-next-line no-console
385
+ console.warn("ResolveOnce.reset dropped was called while processing");
386
+ return undefined as R;
387
+ }
388
+ return this.#syncOrAsync.Unwrap().reset(fn as (c?: CTX) => never) as R;
169
389
  }
170
390
  }
171
391
 
@@ -175,6 +395,7 @@ export interface KeyedParam {
175
395
 
176
396
  export class Keyed<T extends { reset: () => void }, K = string> {
177
397
  protected readonly _map: LRUMap<K, T>;
398
+ // #lock = new ResolveSeq<T, K>();
178
399
 
179
400
  readonly factory: (key: K) => T;
180
401
  constructor(factory: (key: K) => T, params: Partial<KeyedParam>) {
@@ -217,6 +438,14 @@ export class Keyed<T extends { reset: () => void }, K = string> {
217
438
  return this._map.has(key);
218
439
  }
219
440
 
441
+ // lock<R extends Promisable<T>>(fn: (map: LRUMap<K, T>) => R): Promise<UnPromisify<R>> {
442
+ // return this.#lock.add(() => fn(this._map));
443
+ // }
444
+
445
+ delete(key: K): void {
446
+ this._map.delete(key);
447
+ }
448
+
220
449
  unget(key: K): void {
221
450
  const keyed = this._map.get(key);
222
451
  keyed?.reset();
@@ -241,14 +470,13 @@ export class KeyedResolvOnce<T, K = string> extends Keyed<ResolveOnce<T, K>, K>
241
470
 
242
471
  *entries(): IterableIterator<KeyItem<K, T>> {
243
472
  for (const [k, v] of this._map.entries()) {
244
- if (!v._onceDone) {
473
+ if (!v.ready) {
245
474
  continue;
246
475
  }
247
- if (v._onceError) {
248
- yield { key: k, value: Result.Err<T>(v._onceError) };
476
+ if (v.error) {
477
+ yield { key: k, value: Result.Err<T>(v.error) };
249
478
  } else {
250
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
251
- yield { key: k, value: Result.Ok<T>(v._onceValue!) };
479
+ yield { key: k, value: Result.Ok<T>(v.value as T) };
252
480
  }
253
481
  }
254
482
  }
@@ -268,15 +496,15 @@ export class KeyedResolvSeq<T, K = string> extends Keyed<ResolveSeq<T, K>, K> {
268
496
  }
269
497
  }
270
498
 
271
- class LazyContainer<T> {
499
+ class LazyContainer<T extends Promisable<unknown>> {
272
500
  readonly resolveOnce = new ResolveOnce<T>();
273
501
 
274
- call<R>(fn: () => R): () => ReturnType<typeof fn> {
502
+ call<R extends Promisable<UnPromisify<T>>>(fn: () => R): () => ReturnType<typeof fn> {
275
503
  return () => this.resolveOnce.once(fn);
276
504
  }
277
505
  }
278
506
 
279
- export function Lazy<R>(fn: () => R): () => ReturnType<typeof fn> {
280
- const lazy = new LazyContainer();
281
- return lazy.call(fn);
507
+ export function Lazy<R extends Promisable<unknown>>(fn: () => R): () => ReturnType<typeof fn> {
508
+ const lazy = new LazyContainer<R>();
509
+ return lazy.call(fn as () => Promisable<UnPromisify<R>>) as () => ReturnType<typeof fn>;
282
510
  }
@@ -1 +1 @@
1
- {"version":3,"file":"future.d.ts","sourceRoot":"","sources":["../../../src/future.ts"],"names":[],"mappings":"AAAA,qBAAa,MAAM,CAAC,CAAC;;IASnB,cAKC;IAEK,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,CAE5B;IAED,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAEtB;IACD,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAE5B;CACF"}
1
+ {"version":3,"file":"future.d.ts","sourceRoot":"","sources":["../../../src/future.ts"],"names":[],"mappings":"AAAA,qBAAa,MAAM,CAAC,CAAC;;IAUnB,cAKC;IAED,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,CAEtB;IAED,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAEtB;IACD,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAE5B;CACF"}
package/ts/cjs/future.js CHANGED
@@ -15,7 +15,7 @@ class Future {
15
15
  this.#rejectFn = reject;
16
16
  });
17
17
  }
18
- async asPromise() {
18
+ asPromise() {
19
19
  return this.#promise;
20
20
  }
21
21
  resolve(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"future.js","sourceRoot":"","sources":["../../../src/future.ts"],"names":[],"mappings":";;;AAAA;IACW,QAAQ,CAAa;IAC9B,UAAU,GAAuB,GAAG,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAAA,CAC7D,CAAC;IACF,SAAS,GAA8B,GAAG,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAAA,CAC7D,CAAC;IAEF,cAAc;QACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QAAA,CACzB,CAAC,CAAC;IAAA,CACJ;IAED,KAAK,CAAC,SAAS,GAAe;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC;IAAA,CACtB;IAED,OAAO,CAAC,KAAQ,EAAQ;QACtB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAAA,CACxB;IACD,MAAM,CAAC,MAAe,EAAQ;QAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAAA,CACxB;CACF"}
1
+ {"version":3,"file":"future.js","sourceRoot":"","sources":["../../../src/future.ts"],"names":[],"mappings":";;;AAAA;IAEW,QAAQ,CAAa;IAC9B,UAAU,GAAuB,GAAG,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAAA,CAC7D,CAAC;IACF,SAAS,GAA8B,GAAG,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAAA,CAC7D,CAAC;IAEF,cAAc;QACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QAAA,CACzB,CAAC,CAAC;IAAA,CACJ;IAED,SAAS,GAAe;QACtB,OAAO,IAAI,CAAC,QAAQ,CAAC;IAAA,CACtB;IAED,OAAO,CAAC,KAAQ,EAAQ;QACtB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAAA,CACxB;IACD,MAAM,CAAC,MAAe,EAAQ;QAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAAA,CACxB;CACF"}
@@ -1,5 +1,7 @@
1
1
  export type UnPromisify<T> = T extends Promise<infer U> ? U : T;
2
2
  export type WithoutPromise<T> = UnPromisify<T>;
3
+ export type IsNotPromise<T> = T extends Promise<never> ? never : T;
3
4
  export type Promisable<T> = T | Promise<T>;
4
5
  export declare function isPromise<T>(a: T): a is T extends Promise<unknown> ? T : never;
6
+ export declare function isNotPromise<T>(a: T): T;
5
7
  //# sourceMappingURL=is-promise.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-promise.d.ts","sourceRoot":"","sources":["../../../src/is-promise.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAChE,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AAE/C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAE3C,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAY9E"}
1
+ {"version":3,"file":"is-promise.d.ts","sourceRoot":"","sources":["../../../src/is-promise.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAChE,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AAE/C,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAEnE,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAE3C,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAY9E;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAEvC"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isPromise = isPromise;
4
+ exports.isNotPromise = isNotPromise;
4
5
  function isPromise(a) {
5
6
  const mayBe = a;
6
7
  return (mayBe instanceof Promise ||
@@ -10,4 +11,7 @@ function isPromise(a) {
10
11
  typeof mayBe.catch === "function" &&
11
12
  typeof mayBe.finally === "function"));
12
13
  }
14
+ function isNotPromise(a) {
15
+ return !isPromise(a);
16
+ }
13
17
  //# sourceMappingURL=is-promise.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-promise.js","sourceRoot":"","sources":["../../../src/is-promise.ts"],"names":[],"mappings":";;;AAKA,mBAA6B,CAAI,EAA+C;IAC9E,MAAM,KAAK,GAAG,CAA4E,CAAC;IAC3F,OAAO,CACL,KAAK,YAAY,OAAO;QACxB,CAAC,CAAC,CACA,KAAK;YACL,KAAK,KAAK,IAAI;YACd,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU;YAChC,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU;YACjC,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CACpC,CACF,CAAC;AAAA,CACH"}
1
+ {"version":3,"file":"is-promise.js","sourceRoot":"","sources":["../../../src/is-promise.ts"],"names":[],"mappings":";;;;AAOA,mBAA6B,CAAI,EAA+C;IAC9E,MAAM,KAAK,GAAG,CAA4E,CAAC;IAC3F,OAAO,CACL,KAAK,YAAY,OAAO;QACxB,CAAC,CAAC,CACA,KAAK;YACL,KAAK,KAAK,IAAI;YACd,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU;YAChC,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU;YACjC,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CACpC,CACF,CAAC;AAAA,CACH;AAED,sBAAgC,CAAI,EAAK;IACvC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAM,CAAC;AAAA,CAC3B"}
@@ -3,6 +3,7 @@ export declare abstract class Option<T> {
3
3
  static None<T>(): Option<T>;
4
4
  static Is<T>(t: unknown): t is Option<T>;
5
5
  static From<T>(t?: T): Option<T>;
6
+ toValue(): T | undefined;
6
7
  IsNone(): boolean;
7
8
  IsSome(): boolean;
8
9
  Unwrap(): T;
@@ -1 +1 @@
1
- {"version":3,"file":"option.d.ts","sourceRoot":"","sources":["../../../src/option.ts"],"names":[],"mappings":"AAAA,8BAAsB,MAAM,CAAC,CAAC;IAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAE9B;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAE1B;IAED,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAEvC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAK/B;IAED,MAAM,IAAI,OAAO,CAEhB;IAED,MAAM,IAAI,OAAO,CAEhB;IACD,MAAM,IAAI,CAAC,CAEV;IAED,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;CACtB;AAED,qBAAa,IAAI,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,CAAI;IACd,YAAY,EAAE,EAAE,CAAC,EAGhB;IAED,OAAO,IAAI,OAAO,CAEjB;IACD,OAAO,IAAI,OAAO,CAEjB;IACD,MAAM,IAAI,CAAC,CAEV;CACF;AAED,qBAAa,IAAI,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IACpC,OAAO,IAAI,OAAO,CAEjB;IACD,OAAO,IAAI,OAAO,CAEjB;IACD,MAAM,IAAI,CAAC,CAEV;CACF;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"option.d.ts","sourceRoot":"","sources":["../../../src/option.ts"],"names":[],"mappings":"AAAA,8BAAsB,MAAM,CAAC,CAAC;IAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAE9B;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAE1B;IAED,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAEvC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAK/B;IAED,OAAO,IAAI,CAAC,GAAG,SAAS,CAEvB;IAED,MAAM,IAAI,OAAO,CAEhB;IAED,MAAM,IAAI,OAAO,CAEhB;IACD,MAAM,IAAI,CAAC,CAEV;IAED,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;CACtB;AAED,qBAAa,IAAI,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,CAAI;IACd,YAAY,EAAE,EAAE,CAAC,EAGhB;IAED,OAAO,IAAI,OAAO,CAEjB;IACD,OAAO,IAAI,OAAO,CAEjB;IACD,MAAM,IAAI,CAAC,CAEV;CACF;AAED,qBAAa,IAAI,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IACpC,OAAO,IAAI,OAAO,CAEjB;IACD,OAAO,IAAI,OAAO,CAEjB;IACD,MAAM,IAAI,CAAC,CAEV;CACF;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC"}
package/ts/cjs/option.js CHANGED
@@ -17,6 +17,9 @@ class Option {
17
17
  }
18
18
  return new Some(t);
19
19
  }
20
+ toValue() {
21
+ return this.is_some() ? this.unwrap() : undefined;
22
+ }
20
23
  IsNone() {
21
24
  return this.is_none();
22
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"option.js","sourceRoot":"","sources":["../../../src/option.ts"],"names":[],"mappings":";;;AAAA;IACE,MAAM,CAAC,IAAI,CAAI,CAAI,EAAa;QAC9B,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CACpB;IAED,MAAM,CAAC,IAAI,GAAiB;QAC1B,OAAO,IAAI,IAAI,EAAE,CAAC;IAAA,CACnB;IAED,MAAM,CAAC,EAAE,CAAI,CAAU,EAAkB;QACvC,OAAO,CAAC,YAAY,MAAM,CAAC;IAAA,CAC5B;IAED,MAAM,CAAC,IAAI,CAAI,CAAK,EAAa;QAC/B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CACpB;IAED,MAAM,GAAY;QAChB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACvB;IAED,MAAM,GAAY;QAChB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACvB;IACD,MAAM,GAAM;QACV,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IAAA,CACtB;CAKF;;AAED,UAAqB,SAAQ,MAAS;IAC5B,EAAE,CAAI;IACd,YAAY,EAAK,EAAE;QACjB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IAAA,CACd;IAED,OAAO,GAAY;QACjB,OAAO,KAAK,CAAC;IAAA,CACd;IACD,OAAO,GAAY;QACjB,OAAO,IAAI,CAAC;IAAA,CACb;IACD,MAAM,GAAM;QACV,OAAO,IAAI,CAAC,EAAE,CAAC;IAAA,CAChB;CACF;;AAED,UAAqB,SAAQ,MAAS;IACpC,OAAO,GAAY;QACjB,OAAO,IAAI,CAAC;IAAA,CACb;IACD,OAAO,GAAY;QACjB,OAAO,KAAK,CAAC;IAAA,CACd;IACD,MAAM,GAAM;QACV,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;IAAA,CAChC;CACF"}
1
+ {"version":3,"file":"option.js","sourceRoot":"","sources":["../../../src/option.ts"],"names":[],"mappings":";;;AAAA;IACE,MAAM,CAAC,IAAI,CAAI,CAAI,EAAa;QAC9B,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CACpB;IAED,MAAM,CAAC,IAAI,GAAiB;QAC1B,OAAO,IAAI,IAAI,EAAE,CAAC;IAAA,CACnB;IAED,MAAM,CAAC,EAAE,CAAI,CAAU,EAAkB;QACvC,OAAO,CAAC,YAAY,MAAM,CAAC;IAAA,CAC5B;IAED,MAAM,CAAC,IAAI,CAAI,CAAK,EAAa;QAC/B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CACpB;IAED,OAAO,GAAkB;QACvB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAAA,CACnD;IAED,MAAM,GAAY;QAChB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACvB;IAED,MAAM,GAAY;QAChB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACvB;IACD,MAAM,GAAM;QACV,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IAAA,CACtB;CAKF;;AAED,UAAqB,SAAQ,MAAS;IAC5B,EAAE,CAAI;IACd,YAAY,EAAK,EAAE;QACjB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IAAA,CACd;IAED,OAAO,GAAY;QACjB,OAAO,KAAK,CAAC;IAAA,CACd;IACD,OAAO,GAAY;QACjB,OAAO,IAAI,CAAC;IAAA,CACb;IACD,MAAM,GAAM;QACV,OAAO,IAAI,CAAC,EAAE,CAAC;IAAA,CAChB;CACF;;AAED,UAAqB,SAAQ,MAAS;IACpC,OAAO,GAAY;QACjB,OAAO,IAAI,CAAC;IAAA,CACb;IACD,OAAO,GAAY;QACjB,OAAO,KAAK,CAAC;IAAA,CACd;IACD,MAAM,GAAM;QACV,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;IAAA,CAChC;CACF"}