@adviser/cement 0.4.34 → 0.4.36

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 (173) hide show
  1. package/cjs/cli/patch-version-cmd.cjs +30 -26
  2. package/cjs/cli/patch-version-cmd.cjs.map +1 -1
  3. package/cjs/cli/patch-version-cmd.d.ts.map +1 -1
  4. package/cjs/coerce-binary.cjs +2 -1
  5. package/cjs/coerce-binary.cjs.map +1 -1
  6. package/cjs/coerce-binary.d.ts.map +1 -1
  7. package/cjs/crypto.cjs +2 -1
  8. package/cjs/crypto.cjs.map +1 -1
  9. package/cjs/crypto.d.ts.map +1 -1
  10. package/cjs/import-meta-env.commonjs.cjs +10 -0
  11. package/cjs/import-meta-env.commonjs.cjs.map +1 -0
  12. package/cjs/import-meta-env.commonjs.d.ts +4 -0
  13. package/cjs/import-meta-env.commonjs.d.ts.map +1 -0
  14. package/cjs/load-asset.cjs.map +1 -1
  15. package/cjs/lru-map-set.cjs +34 -20
  16. package/cjs/lru-map-set.cjs.map +1 -1
  17. package/cjs/lru-map-set.d.ts +27 -23
  18. package/cjs/lru-map-set.d.ts.map +1 -1
  19. package/cjs/lru-map-set.test.cjs +20 -0
  20. package/cjs/lru-map-set.test.cjs.map +1 -1
  21. package/cjs/mutable-url.cjs.map +1 -1
  22. package/cjs/mutable-url.d.ts.map +1 -1
  23. package/cjs/resolve-once.cjs +8 -6
  24. package/cjs/resolve-once.cjs.map +1 -1
  25. package/cjs/resolve-once.d.ts +27 -17
  26. package/cjs/resolve-once.d.ts.map +1 -1
  27. package/cjs/resolve-once.test.cjs +4 -4
  28. package/cjs/resolve-once.test.cjs.map +1 -1
  29. package/cjs/sys-env.cjs +3 -1
  30. package/cjs/sys-env.cjs.map +1 -1
  31. package/cjs/sys-env.d.ts +1 -0
  32. package/cjs/sys-env.d.ts.map +1 -1
  33. package/cjs/sys-env.test.cjs +6 -0
  34. package/cjs/sys-env.test.cjs.map +1 -1
  35. package/cjs/utils/stripper.cjs +10 -5
  36. package/cjs/utils/stripper.cjs.map +1 -1
  37. package/cjs/utils/stripper.d.ts.map +1 -1
  38. package/cjs/utils/stripper.test.cjs +18 -0
  39. package/cjs/utils/stripper.test.cjs.map +1 -1
  40. package/cjs/version.cjs +1 -1
  41. package/deno.json +15 -3
  42. package/esm/cli/patch-version-cmd.d.ts.map +1 -1
  43. package/esm/cli/patch-version-cmd.js +30 -26
  44. package/esm/cli/patch-version-cmd.js.map +1 -1
  45. package/esm/coerce-binary.d.ts.map +1 -1
  46. package/esm/coerce-binary.js +2 -1
  47. package/esm/coerce-binary.js.map +1 -1
  48. package/esm/crypto.d.ts.map +1 -1
  49. package/esm/crypto.js +2 -1
  50. package/esm/crypto.js.map +1 -1
  51. package/esm/import-meta-env.module.d.ts +4 -0
  52. package/esm/import-meta-env.module.d.ts.map +1 -0
  53. package/esm/import-meta-env.module.js +42 -0
  54. package/esm/import-meta-env.module.js.map +1 -0
  55. package/esm/load-asset.js.map +1 -1
  56. package/esm/lru-map-set.d.ts +27 -23
  57. package/esm/lru-map-set.d.ts.map +1 -1
  58. package/esm/lru-map-set.js +34 -20
  59. package/esm/lru-map-set.js.map +1 -1
  60. package/esm/lru-map-set.test.js +20 -0
  61. package/esm/lru-map-set.test.js.map +1 -1
  62. package/esm/mutable-url.d.ts.map +1 -1
  63. package/esm/mutable-url.js.map +1 -1
  64. package/esm/resolve-once.d.ts +27 -17
  65. package/esm/resolve-once.d.ts.map +1 -1
  66. package/esm/resolve-once.js +8 -6
  67. package/esm/resolve-once.js.map +1 -1
  68. package/esm/resolve-once.test.js +4 -4
  69. package/esm/resolve-once.test.js.map +1 -1
  70. package/esm/sys-env.d.ts +1 -0
  71. package/esm/sys-env.d.ts.map +1 -1
  72. package/esm/sys-env.js +3 -1
  73. package/esm/sys-env.js.map +1 -1
  74. package/esm/sys-env.test.js +6 -0
  75. package/esm/sys-env.test.js.map +1 -1
  76. package/esm/utils/stripper.d.ts.map +1 -1
  77. package/esm/utils/stripper.js +10 -5
  78. package/esm/utils/stripper.js.map +1 -1
  79. package/esm/utils/stripper.test.js +18 -0
  80. package/esm/utils/stripper.test.js.map +1 -1
  81. package/esm/version.js +1 -1
  82. package/package.json +12 -7
  83. package/src/cli/patch-version-cmd.ts +36 -31
  84. package/src/coerce-binary.ts +2 -1
  85. package/src/crypto.ts +7 -9
  86. package/src/import-meta-env.commonjs.ts +9 -0
  87. package/src/import-meta-env.module.ts +46 -0
  88. package/src/load-asset.ts +1 -1
  89. package/src/lru-map-set.ts +75 -53
  90. package/src/mutable-url.ts +25 -25
  91. package/src/resolve-once.ts +39 -25
  92. package/src/sys-env.ts +6 -1
  93. package/src/utils/stripper.ts +11 -8
  94. package/ts/cjs/cli/patch-version-cmd.d.ts.map +1 -1
  95. package/ts/cjs/cli/patch-version-cmd.js +30 -26
  96. package/ts/cjs/cli/patch-version-cmd.js.map +1 -1
  97. package/ts/cjs/coerce-binary.d.ts.map +1 -1
  98. package/ts/cjs/coerce-binary.js +2 -1
  99. package/ts/cjs/coerce-binary.js.map +1 -1
  100. package/ts/cjs/crypto.d.ts.map +1 -1
  101. package/ts/cjs/crypto.js +2 -1
  102. package/ts/cjs/crypto.js.map +1 -1
  103. package/ts/cjs/import-meta-env.commonjs.d.ts +4 -0
  104. package/ts/cjs/import-meta-env.commonjs.d.ts.map +1 -0
  105. package/ts/cjs/import-meta-env.commonjs.js +10 -0
  106. package/ts/cjs/import-meta-env.commonjs.js.map +1 -0
  107. package/ts/cjs/load-asset.js.map +1 -1
  108. package/ts/cjs/lru-map-set.d.ts +27 -23
  109. package/ts/cjs/lru-map-set.d.ts.map +1 -1
  110. package/ts/cjs/lru-map-set.js +34 -20
  111. package/ts/cjs/lru-map-set.js.map +1 -1
  112. package/ts/cjs/lru-map-set.test.js +20 -0
  113. package/ts/cjs/lru-map-set.test.js.map +1 -1
  114. package/ts/cjs/mutable-url.d.ts.map +1 -1
  115. package/ts/cjs/mutable-url.js.map +1 -1
  116. package/ts/cjs/resolve-once.d.ts +27 -17
  117. package/ts/cjs/resolve-once.d.ts.map +1 -1
  118. package/ts/cjs/resolve-once.js +8 -6
  119. package/ts/cjs/resolve-once.js.map +1 -1
  120. package/ts/cjs/resolve-once.test.js +4 -4
  121. package/ts/cjs/resolve-once.test.js.map +1 -1
  122. package/ts/cjs/sys-env.d.ts +1 -0
  123. package/ts/cjs/sys-env.d.ts.map +1 -1
  124. package/ts/cjs/sys-env.js +3 -1
  125. package/ts/cjs/sys-env.js.map +1 -1
  126. package/ts/cjs/sys-env.test.js +6 -0
  127. package/ts/cjs/sys-env.test.js.map +1 -1
  128. package/ts/cjs/utils/stripper.d.ts.map +1 -1
  129. package/ts/cjs/utils/stripper.js +10 -5
  130. package/ts/cjs/utils/stripper.js.map +1 -1
  131. package/ts/cjs/utils/stripper.test.js +18 -0
  132. package/ts/cjs/utils/stripper.test.js.map +1 -1
  133. package/ts/cjs/version.js +1 -1
  134. package/ts/esm/cli/patch-version-cmd.d.ts.map +1 -1
  135. package/ts/esm/cli/patch-version-cmd.js +30 -26
  136. package/ts/esm/cli/patch-version-cmd.js.map +1 -1
  137. package/ts/esm/coerce-binary.d.ts.map +1 -1
  138. package/ts/esm/coerce-binary.js +2 -1
  139. package/ts/esm/coerce-binary.js.map +1 -1
  140. package/ts/esm/crypto.d.ts.map +1 -1
  141. package/ts/esm/crypto.js +2 -1
  142. package/ts/esm/crypto.js.map +1 -1
  143. package/ts/esm/import-meta-env.module.d.ts +4 -0
  144. package/ts/esm/import-meta-env.module.d.ts.map +1 -0
  145. package/ts/esm/import-meta-env.module.js +42 -0
  146. package/ts/esm/import-meta-env.module.js.map +1 -0
  147. package/ts/esm/load-asset.js.map +1 -1
  148. package/ts/esm/lru-map-set.d.ts +27 -23
  149. package/ts/esm/lru-map-set.d.ts.map +1 -1
  150. package/ts/esm/lru-map-set.js +34 -20
  151. package/ts/esm/lru-map-set.js.map +1 -1
  152. package/ts/esm/lru-map-set.test.js +20 -0
  153. package/ts/esm/lru-map-set.test.js.map +1 -1
  154. package/ts/esm/mutable-url.d.ts.map +1 -1
  155. package/ts/esm/mutable-url.js.map +1 -1
  156. package/ts/esm/resolve-once.d.ts +27 -17
  157. package/ts/esm/resolve-once.d.ts.map +1 -1
  158. package/ts/esm/resolve-once.js +8 -6
  159. package/ts/esm/resolve-once.js.map +1 -1
  160. package/ts/esm/resolve-once.test.js +4 -4
  161. package/ts/esm/resolve-once.test.js.map +1 -1
  162. package/ts/esm/sys-env.d.ts +1 -0
  163. package/ts/esm/sys-env.d.ts.map +1 -1
  164. package/ts/esm/sys-env.js +3 -1
  165. package/ts/esm/sys-env.js.map +1 -1
  166. package/ts/esm/sys-env.test.js +6 -0
  167. package/ts/esm/sys-env.test.js.map +1 -1
  168. package/ts/esm/utils/stripper.d.ts.map +1 -1
  169. package/ts/esm/utils/stripper.js +10 -5
  170. package/ts/esm/utils/stripper.js.map +1 -1
  171. package/ts/esm/utils/stripper.test.js +18 -0
  172. package/ts/esm/utils/stripper.test.js.map +1 -1
  173. package/ts/esm/version.js +1 -1
@@ -1,18 +1,24 @@
1
1
  import { AppContext } from "./app-context.js";
2
2
 
3
- export interface LRUParam {
4
- readonly maxEntries: number;
5
- readonly maxAge: number; // not implemented
3
+ interface MutableLRUParam<T, K> {
4
+ evict: (param: LRUParam<T, K>, newItem: T, map: LRUMap<K, T>) => boolean;
5
+ // is called if the params are changed
6
+ // default it removes the least recently accessed
7
+ refresh: (param: LRUParam<T, K>, map: Map<K, LRUItem<T>>) => void;
8
+ maxEntries: number;
9
+ maxAge: number; // not implemented
6
10
  }
7
11
 
12
+ export type LRUParam<T = string, K = string> = Readonly<MutableLRUParam<T, K>>;
13
+
8
14
  export class LRUSet<T> {
9
15
  private readonly _lruMap: LRUMap<T, T>;
10
16
 
11
- constructor(param: Partial<LRUParam> = {}) {
17
+ constructor(param: Partial<LRUParam<T, T>> = {}) {
12
18
  this._lruMap = new LRUMap<T, T>(param);
13
19
  }
14
20
 
15
- setParam(param: Partial<LRUParam> = {}): void {
21
+ setParam(param: Partial<LRUParam<T, T>> = {}): void {
16
22
  this._lruMap.setParam(param);
17
23
  }
18
24
 
@@ -47,22 +53,40 @@ export class LRUSet<T> {
47
53
 
48
54
  export interface LRUCtx<T, K> {
49
55
  readonly update: boolean;
50
- readonly ref: LRUMap<T, K>;
56
+ readonly ref: LRUMap<K, T>;
51
57
  readonly stats: LRUMap<T, K>["stats"];
52
- readonly item: LRUItem<K>;
58
+ readonly item: LRUItem<T>;
53
59
  }
54
60
 
55
- export interface LRUItem<K> {
56
- readonly value: K;
61
+ export interface LRUItem<V> {
62
+ readonly value: V;
57
63
  ctx?: AppContext;
58
64
  }
59
65
 
60
- export type LRUMapFn<K, T> = (key: K, value: T, meta: LRUCtx<K, T>) => void;
66
+ export type LRUMapFn<K, T> = (value: T, key: K, meta: LRUCtx<K, T>) => void;
61
67
  export type UnregFn = () => void;
62
68
 
63
- export class LRUMap<T, K> {
64
- private _map: Map<T, LRUItem<K>> = new Map<T, LRUItem<K>>();
65
- private param: LRUParam;
69
+ function defaultRefresh<V, K>(param: LRUParam<V, K>, map: Map<K, LRUItem<V>>): void {
70
+ if (param.maxEntries > 0 && map.size > param.maxEntries) {
71
+ const toDelete: K[] = [];
72
+ let cacheSize = map.size;
73
+ for (const key of map.keys()) {
74
+ if (cacheSize > param.maxEntries) {
75
+ toDelete.push(key);
76
+ cacheSize--;
77
+ } else {
78
+ break;
79
+ }
80
+ }
81
+ for (const key of toDelete) {
82
+ map.delete(key);
83
+ }
84
+ }
85
+ }
86
+
87
+ export class LRUMap<K, V> {
88
+ private _map: Map<K, LRUItem<V>> = new Map<K, LRUItem<V>>();
89
+ private param: MutableLRUParam<V, K>;
66
90
 
67
91
  readonly stats = {
68
92
  gets: 0,
@@ -70,23 +94,25 @@ export class LRUMap<T, K> {
70
94
  deletes: 0,
71
95
  };
72
96
 
73
- constructor(c: Partial<LRUParam> = {}) {
97
+ constructor(c: Partial<LRUParam<V, K>> = {}) {
74
98
  this.param = {
75
99
  maxEntries: c.maxEntries || 100,
76
100
  maxAge: c.maxAge || 0,
101
+ evict: c.evict || ((param, _newItem, map): boolean => param.maxEntries > 0 && map.size >= param.maxEntries),
102
+ refresh: c.refresh || ((param: LRUParam<V, K>, map: Map<K, LRUItem<V>>): void => defaultRefresh(param, map)),
77
103
  };
78
104
  }
79
105
 
80
- private _onSetFns: Map<string, LRUMapFn<T, K>> = new Map<string, LRUMapFn<T, K>>();
81
- onSet(fn: LRUMapFn<T, K>): UnregFn {
106
+ private _onSetFns: Map<string, LRUMapFn<V, K>> = new Map<string, LRUMapFn<V, K>>();
107
+ onSet(fn: LRUMapFn<V, K>): UnregFn {
82
108
  const id = Math.random().toString(36);
83
109
  this._onSetFns.set(id, fn);
84
110
  return () => {
85
111
  this._onSetFns.delete(id);
86
112
  };
87
113
  }
88
- private _onDeleteFns: Map<string, LRUMapFn<T, K>> = new Map<string, LRUMapFn<T, K>>();
89
- onDelete(fn: LRUMapFn<T, K>): UnregFn {
114
+ private _onDeleteFns: Map<string, LRUMapFn<V, K>> = new Map<string, LRUMapFn<V, K>>();
115
+ onDelete(fn: LRUMapFn<V, K>): UnregFn {
90
116
  const id = Math.random().toString(36);
91
117
  this._onDeleteFns.set(id, fn);
92
118
  return () => {
@@ -94,39 +120,35 @@ export class LRUMap<T, K> {
94
120
  };
95
121
  }
96
122
 
97
- private touch(key: T): LRUItem<K> {
123
+ private touch(key: K): LRUItem<V> {
98
124
  if (!this._map.has(key)) {
99
125
  throw new Error(`key not found in cache: ${key as unknown as string}`);
100
126
  }
101
127
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
102
- const value = this._map.get(key) as LRUItem<K>;
128
+ const value = this._map.get(key) as LRUItem<V>;
103
129
  this._map.delete(key);
104
130
  this._map.set(key, value);
105
131
  return value;
106
132
  }
107
133
 
108
- setParam(param: Partial<LRUParam> = {}): void {
134
+ setParam(param: Partial<LRUParam<V, K>> = {}): void {
135
+ if (param.evict) {
136
+ this.param.evict = param.evict;
137
+ }
138
+ if (param.refresh) {
139
+ this.param.refresh = param.refresh;
140
+ }
109
141
  if (typeof param.maxEntries === "number") {
110
- (this.param as { maxEntries: number }).maxEntries = param.maxEntries;
111
- if (param.maxEntries > 0 && this._map.size > param.maxEntries) {
112
- const toDelete: T[] = [];
113
- let cacheSize = this._map.size;
114
- for (const key of this._map.keys()) {
115
- if (cacheSize > param.maxEntries) {
116
- toDelete.push(key);
117
- cacheSize--;
118
- } else {
119
- break;
120
- }
121
- }
122
- for (const key of toDelete) {
123
- this._map.delete(key);
124
- }
125
- }
142
+ this.param.maxEntries = param.maxEntries;
143
+ }
144
+ if (typeof param.maxAge === "number") {
145
+ this.param.maxAge = param.maxAge;
126
146
  }
147
+
148
+ this.param.refresh(this.param, this._map);
127
149
  }
128
150
 
129
- has(key: T): boolean {
151
+ has(key: K): boolean {
130
152
  return this._map.has(key);
131
153
  }
132
154
 
@@ -134,22 +156,22 @@ export class LRUMap<T, K> {
134
156
  return this._map.size;
135
157
  }
136
158
 
137
- async getSet(key: T, createFN: (key: T) => Promise<K>): Promise<K | undefined> {
159
+ async getSet(key: K, createFN: (key: K) => Promise<V>): Promise<V | undefined> {
138
160
  const val = this.get(key);
139
161
  if (val) {
140
162
  return val;
141
163
  } else {
142
164
  const val = await createFN(key);
143
- this.set(key, val as K);
165
+ this.set(key, val as V);
144
166
  return val;
145
167
  }
146
168
  }
147
169
 
148
- get(key: T): K | undefined {
170
+ get(key: K): V | undefined {
149
171
  return this.getItem(key)?.value;
150
172
  }
151
173
 
152
- getItem(key: T): LRUItem<K> | undefined {
174
+ getItem(key: K): LRUItem<V> | undefined {
153
175
  if (this._map.has(key)) {
154
176
  this.stats.gets++;
155
177
  return this.touch(key);
@@ -157,14 +179,14 @@ export class LRUMap<T, K> {
157
179
  return undefined;
158
180
  }
159
181
 
160
- private buildItem(item: LRUItem<K> | undefined, value: K): LRUItem<K> {
182
+ private buildItem(item: LRUItem<V> | undefined, value: V): LRUItem<V> {
161
183
  return {
162
184
  ...item,
163
185
  value,
164
186
  };
165
187
  }
166
188
 
167
- set(key: T, value: K): void {
189
+ set(key: K, value: V): void {
168
190
  const update = this._map.has(key);
169
191
  let item = this._map.get(key);
170
192
  if (update) {
@@ -175,13 +197,13 @@ export class LRUMap<T, K> {
175
197
  this._map.delete(key);
176
198
  }
177
199
  item = this.buildItem(item, value);
178
- if (this.param.maxEntries > 0 && this._map.size >= this.param.maxEntries) {
200
+ if (this.param.evict(this.param, value, this)) {
179
201
  // delete the least recently accessed
180
202
  // const key = Array.from(this.cache.keys())[0];
181
203
  // this.cache.delete(key) or
182
- const v = this._map.keys().next();
183
- if (!v.done) {
184
- this._map.delete(v.value as T);
204
+ const k = this._map.keys().next();
205
+ if (!k.done) {
206
+ this._map.delete(k.value as K);
185
207
  }
186
208
  }
187
209
  this._map.set(key, item);
@@ -189,7 +211,7 @@ export class LRUMap<T, K> {
189
211
  this._onSetFns.forEach((fn) => fn(key, item?.value, this.buildItemCtx(item, update)));
190
212
  }
191
213
 
192
- private buildItemCtx(item: LRUItem<K>, update: boolean): LRUCtx<T, K> {
214
+ private buildItemCtx(item: LRUItem<V>, update: boolean): LRUCtx<V, K> {
193
215
  return {
194
216
  update,
195
217
  ref: this,
@@ -198,10 +220,10 @@ export class LRUMap<T, K> {
198
220
  };
199
221
  }
200
222
 
201
- delete(key: T): void {
223
+ delete(key: K): void {
202
224
  if (this._map.has(key)) {
203
225
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
204
- const item = this._map.get(key) as LRUItem<K>;
226
+ const item = this._map.get(key) as LRUItem<V>;
205
227
  this._onDeleteFns.forEach((fn) => fn(key, item?.value, this.buildItemCtx(item, true)));
206
228
  this._map.delete(key);
207
229
  this.stats.deletes++;
@@ -217,13 +239,13 @@ export class LRUMap<T, K> {
217
239
  this._map.clear();
218
240
  }
219
241
 
220
- forEach(fn: (value: K, key: T, ctx: LRUCtx<T, K>) => void): void {
242
+ forEach(fn: (value: V, key: K, ctx: LRUCtx<V, K>) => void): void {
221
243
  this._map.forEach((v, k) => {
222
244
  fn(v.value, k, this.buildItemCtx(v, false));
223
245
  });
224
246
  }
225
247
 
226
- *entries(): IterableIterator<[T, K, LRUCtx<T, K>]> {
248
+ *entries(): IterableIterator<[K, V, LRUCtx<V, K>]> {
227
249
  for (const [key, value] of this._map.entries()) {
228
250
  yield [key, value.value, this.buildItemCtx(value, true)];
229
251
  }
@@ -62,7 +62,7 @@ export class ReadonlyURL extends URL {
62
62
  // this.hash = this._sysURL.hash;
63
63
  }
64
64
 
65
- set origin(h: string) {
65
+ override set origin(h: string) {
66
66
  throw new Error("origin is readonly");
67
67
  }
68
68
 
@@ -70,7 +70,7 @@ export class ReadonlyURL extends URL {
70
70
  return this.toString();
71
71
  }
72
72
 
73
- set href(h: string) {
73
+ override set href(h: string) {
74
74
  throw new Error("href is readonly");
75
75
  }
76
76
 
@@ -78,7 +78,7 @@ export class ReadonlyURL extends URL {
78
78
  return this._sysURL.password;
79
79
  }
80
80
 
81
- set password(h: string) {
81
+ override set password(h: string) {
82
82
  throw new Error("password is readonly");
83
83
  }
84
84
 
@@ -86,11 +86,11 @@ export class ReadonlyURL extends URL {
86
86
  return this._sysURL.username;
87
87
  }
88
88
 
89
- set username(h: string) {
89
+ override set username(h: string) {
90
90
  throw new Error("username is readonly");
91
91
  }
92
92
 
93
- toJSON(): string {
93
+ override toJSON(): string {
94
94
  return this.toString();
95
95
  }
96
96
 
@@ -108,12 +108,12 @@ export class ReadonlyURL extends URL {
108
108
  return this._sysURL.hash;
109
109
  }
110
110
 
111
- set hash(h: string) {
111
+ override set hash(h: string) {
112
112
  throw new Error("hash is readonly");
113
113
  }
114
114
 
115
115
  // Host getter and setter
116
- get host(): string {
116
+ override get host(): string {
117
117
  if (!this._hasHostpart) {
118
118
  throw new Error(
119
119
  `you can use hostname only if protocol is ${this.toString()} ${JSON.stringify(Array.from(hasHostPartProtocols.keys()))}`,
@@ -122,19 +122,19 @@ export class ReadonlyURL extends URL {
122
122
  return this._sysURL.host;
123
123
  }
124
124
 
125
- set host(h: string) {
125
+ override set host(h: string) {
126
126
  throw new Error("host is readonly");
127
127
  }
128
128
 
129
129
  // Hostname getter and setter
130
- get hostname(): string {
130
+ override get hostname(): string {
131
131
  if (!this._hasHostpart) {
132
132
  throw new Error(`you can use hostname only if protocol is ${JSON.stringify(Array.from(hasHostPartProtocols.keys()))}`);
133
133
  }
134
134
  return this._sysURL.hostname;
135
135
  }
136
136
 
137
- set hostname(h: string) {
137
+ override set hostname(h: string) {
138
138
  throw new Error("hostname is readonly");
139
139
  }
140
140
 
@@ -143,7 +143,7 @@ export class ReadonlyURL extends URL {
143
143
  return this._pathname;
144
144
  }
145
145
 
146
- set pathname(h: string) {
146
+ override set pathname(h: string) {
147
147
  throw new Error("pathname is readonly");
148
148
  }
149
149
 
@@ -155,7 +155,7 @@ export class ReadonlyURL extends URL {
155
155
  return this._sysURL.port;
156
156
  }
157
157
 
158
- set port(h: string) {
158
+ override set port(h: string) {
159
159
  throw new Error("port is readonly");
160
160
  }
161
161
 
@@ -164,12 +164,12 @@ export class ReadonlyURL extends URL {
164
164
  return this._protocol;
165
165
  }
166
166
 
167
- set protocol(h: string) {
167
+ override set protocol(h: string) {
168
168
  throw new Error("protocol is readonly");
169
169
  }
170
170
 
171
171
  // Search getter and setter
172
- get search(): string {
172
+ override get search(): string {
173
173
  let search = "";
174
174
  if (this._sysURL.searchParams.size) {
175
175
  for (const [key, value] of Array.from(URLSearchParamsEntries(this._sysURL.searchParams)).sort((a, b) =>
@@ -181,7 +181,7 @@ export class ReadonlyURL extends URL {
181
181
  return search;
182
182
  }
183
183
 
184
- set search(h: string) {
184
+ override set search(h: string) {
185
185
  throw new Error("search is readonly");
186
186
  }
187
187
 
@@ -190,7 +190,7 @@ export class ReadonlyURL extends URL {
190
190
  return this._sysURL.searchParams;
191
191
  }
192
192
 
193
- set searchParams(h: URLSearchParams) {
193
+ override set searchParams(h: URLSearchParams) {
194
194
  throw new Error("searchParams is readonly");
195
195
  }
196
196
 
@@ -216,11 +216,11 @@ export class ReadonlyURL extends URL {
216
216
  export class WritableURL extends ReadonlyURL {
217
217
  // override readonly hash: string;
218
218
 
219
- static readonly fromThrow = (urlStr: string): WritableURL => {
219
+ static override readonly fromThrow = (urlStr: string): WritableURL => {
220
220
  return new WritableURL(urlStr);
221
221
  };
222
222
 
223
- static from(urlStr: string): Result<WritableURL> {
223
+ static override from(urlStr: string): Result<WritableURL> {
224
224
  if (urlRegex.test(urlStr)) {
225
225
  return exception2Result(() => new WritableURL(urlStr));
226
226
  }
@@ -235,24 +235,24 @@ export class WritableURL extends ReadonlyURL {
235
235
  return this.toString();
236
236
  }
237
237
 
238
- [customInspectSymbol](): string {
238
+ override [customInspectSymbol](): string {
239
239
  // make node inspect to show the URL and not crash if URI is not http/https/file
240
240
  return this.toString();
241
241
  }
242
242
 
243
- clone(): WritableURL {
243
+ override clone(): WritableURL {
244
244
  return new WritableURL(this.toString());
245
245
  }
246
246
 
247
- set origin(_h: string) {
247
+ override set origin(_h: string) {
248
248
  throw new Error("don't use origin");
249
249
  }
250
250
 
251
- get href(): string {
251
+ override get href(): string {
252
252
  return super.href;
253
253
  }
254
254
 
255
- set href(h: string) {
255
+ override set href(h: string) {
256
256
  throw new Error("don't use href");
257
257
  }
258
258
 
@@ -260,7 +260,7 @@ export class WritableURL extends ReadonlyURL {
260
260
  return super.password;
261
261
  }
262
262
 
263
- set password(h: string) {
263
+ override set password(h: string) {
264
264
  this._sysURL.password = h;
265
265
  }
266
266
 
@@ -268,7 +268,7 @@ export class WritableURL extends ReadonlyURL {
268
268
  return super.username;
269
269
  }
270
270
 
271
- set username(h: string) {
271
+ override set username(h: string) {
272
272
  this._sysURL.username = h;
273
273
  }
274
274
 
@@ -1,18 +1,21 @@
1
1
  import { Future } from "./future.js";
2
- import { NonPromise, UnPromisify } from "./is-promise.js";
2
+ import { UnPromisify } from "./is-promise.js";
3
3
  import { isPromise } from "./is-promise.js";
4
4
  import { LRUMap, LRUParam, UnregFn } from "./lru-map-set.js";
5
5
  import { Result } from "./result.js";
6
6
  import { Option } from "./option.js";
7
7
 
8
- interface ResolveSeqItem<C, R extends NonPromise<X>, X = string | number | boolean | symbol | object> {
9
- readonly future: Future<R>;
10
- readonly fn: (c?: C) => R | Promise<R>;
8
+ // interface ResolveSeqItem<C, R extends NonPromise<X>, X = string | number | boolean | symbol | object> {
9
+ interface ResolveSeqItem<C, T, R> {
10
+ readonly future: Future<T>;
11
+ readonly fn: (c?: C) => R;
11
12
  readonly id?: number;
12
13
  }
13
14
 
14
- export class ResolveSeq<T extends NonPromise<X>, C = void, X = string | number | boolean | symbol | object> {
15
+ export class ResolveSeq<T, C extends NonNullable<object> = object> {
15
16
  readonly ctx?: C;
17
+ readonly _seqFutures: ResolveSeqItem<C, T, unknown>[] = [];
18
+
16
19
  constructor(ctx?: C) {
17
20
  this.ctx = ctx;
18
21
  }
@@ -29,14 +32,14 @@ export class ResolveSeq<T extends NonPromise<X>, C = void, X = string | number |
29
32
  }
30
33
  return Promise.resolve();
31
34
  }
32
- async _step(item?: ResolveSeqItem<C, T, X>): Promise<void> {
35
+ async _step(item?: ResolveSeqItem<C, T, Promise<T> | T>): Promise<void> {
33
36
  if (!item) {
34
37
  // done
35
38
  this._flushWaiting.forEach((f) => f.resolve());
36
39
  this._flushWaiting?.splice(0, this._flushWaiting.length);
37
40
  return Promise.resolve();
38
41
  }
39
- let value;
42
+ let value: T;
40
43
  try {
41
44
  const promiseOrValue = item.fn(this.ctx);
42
45
  if (isPromise(promiseOrValue)) {
@@ -44,20 +47,19 @@ export class ResolveSeq<T extends NonPromise<X>, C = void, X = string | number |
44
47
  } else {
45
48
  value = promiseOrValue;
46
49
  }
47
- item.future.resolve(value as T);
50
+ item.future.resolve(value);
48
51
  } catch (e) {
49
52
  item.future.reject(e as Error);
50
53
  } finally {
51
54
  this._seqFutures.shift();
52
55
  }
53
- return this._step(this._seqFutures[0]);
56
+ return this._step(this._seqFutures[0] as ResolveSeqItem<C, T, Promise<T> | T>);
54
57
  }
55
- readonly _seqFutures: ResolveSeqItem<C, T, X>[] = [];
56
58
  add<R extends Promise<T> | T>(fn: (c?: C) => R, id?: number): R {
57
59
  const future = new Future<T>();
58
60
  this._seqFutures.push({ future, fn, id });
59
61
  if (this._seqFutures.length === 1) {
60
- void this._step(this._seqFutures[0]); // exit into eventloop
62
+ void this._step(this._seqFutures[0] as ResolveSeqItem<C, T, Promise<T> | T>); // exit into eventloop
61
63
  }
62
64
  return future.asPromise() as R; // as Promise<UnPromisify<R>>;
63
65
  }
@@ -392,18 +394,23 @@ export class ResolveOnce<T, CTX = void> implements ResolveOnceIf<T, CTX> {
392
394
  }
393
395
  }
394
396
 
395
- export interface KeyedParam {
396
- readonly lru: Partial<LRUParam>;
397
+ export interface KeyedParam<K, V> {
398
+ readonly lru: Partial<LRUParam<V, K>>;
397
399
  }
398
400
 
399
- export class Keyed<T extends { reset: () => void }, K = string> {
401
+ type AddKeyedParam<K, V, CTX extends NonNullable<object>> = KeyedParam<K, V> & { readonly ctx: CTX };
402
+
403
+ export class Keyed<T extends { reset: () => void }, K = string, CTX extends NonNullable<object> = object> {
400
404
  protected readonly _map: LRUMap<K, T>;
401
405
  // #lock = new ResolveSeq<T, K>();
406
+ readonly #ctx: CTX;
402
407
 
403
- readonly factory: (key: K) => T;
404
- constructor(factory: (key: K) => T, params: Partial<KeyedParam>) {
408
+ readonly factory: (ctx: AddKey<CTX, K>) => T;
409
+
410
+ constructor(factory: (ctx: AddKey<CTX, K>) => T, ctx: Partial<AddKeyedParam<K, T, CTX>>) {
411
+ this.#ctx = ctx.ctx || ({} as CTX);
405
412
  this.factory = factory;
406
- this._map = new LRUMap<K, T>(params?.lru ?? { maxEntries: -1 });
413
+ this._map = new LRUMap<K, T>(ctx?.lru ?? ({ maxEntries: -1 } as LRUParam<T, K>));
407
414
  }
408
415
 
409
416
  onSet(fn: (key: K, value: T) => void): UnregFn {
@@ -414,7 +421,7 @@ export class Keyed<T extends { reset: () => void }, K = string> {
414
421
  return this._map.onDelete(fn);
415
422
  }
416
423
 
417
- setParam(params: KeyedParam): void {
424
+ setParam(params: KeyedParam<K, T>): void {
418
425
  this._map.setParam(params.lru);
419
426
  }
420
427
 
@@ -428,7 +435,7 @@ export class Keyed<T extends { reset: () => void }, K = string> {
428
435
  }
429
436
  let keyed = this._map.get(key);
430
437
  if (!keyed) {
431
- keyed = this.factory(key);
438
+ keyed = this.factory({ ...this.#ctx, key: key });
432
439
  this._map.set(key, keyed);
433
440
  }
434
441
  return keyed;
@@ -466,9 +473,9 @@ interface KeyItem<K, V> {
466
473
  readonly value: Result<V>;
467
474
  }
468
475
 
469
- export class KeyedResolvOnce<T, K = string> extends Keyed<ResolveOnce<T, K>, K> {
470
- constructor(kp: Partial<KeyedParam> = {}) {
471
- super((key) => new ResolveOnce<T, K>(key), kp);
476
+ export class KeyedResolvOnce<T, K = string, CTX extends NonNullable<object> = object> extends Keyed<ResolveOnce<T, CTX>, K, CTX> {
477
+ constructor(kp: Partial<AddKeyedParam<K, ResolveOnce<T, CTX>, CTX>> = {}) {
478
+ super((ctx) => new ResolveOnce<T, AddKey<CTX, K>>(ctx), kp);
472
479
  }
473
480
 
474
481
  *entries(): IterableIterator<KeyItem<K, T>> {
@@ -493,9 +500,16 @@ export class KeyedResolvOnce<T, K = string> extends Keyed<ResolveOnce<T, K>, K>
493
500
  }
494
501
  }
495
502
 
496
- export class KeyedResolvSeq<T extends NonPromise<never>, K = string> extends Keyed<ResolveSeq<T, K>, K> {
497
- constructor(kp: Partial<KeyedParam> = {}) {
498
- super((key) => new ResolveSeq<T, K>(key), kp);
503
+ type AddKey<X extends NonNullable<object>, K> = X & { key: K };
504
+ type WithCTX<K, T, CTX extends NonNullable<object>> = KeyedParam<K, ResolveSeq<T, AddKey<CTX, K>>> & { readonly ctx: CTX };
505
+
506
+ export class KeyedResolvSeq<T extends NonNullable<unknown>, K = string, CTX extends NonNullable<object> = object> extends Keyed<
507
+ ResolveSeq<T, AddKey<CTX, K>>,
508
+ K,
509
+ CTX
510
+ > {
511
+ constructor(kp: Partial<WithCTX<K, T, CTX>> = {}) {
512
+ super((ctx) => new ResolveSeq<T, AddKey<CTX, K>>(ctx), kp);
499
513
  }
500
514
  }
501
515
 
package/src/sys-env.ts CHANGED
@@ -5,6 +5,7 @@ import { CFEnvActions } from "./cf/cf-env-actions.js";
5
5
  import { KeyedResolvOnce } from "./resolve-once.js";
6
6
  import { Result } from "./result.js";
7
7
  import { getParamsResult, KeysParam } from "./utils/get-params-result.js";
8
+ import { wrapImportMetaEnv, testInjectImportMetaEnv } from "@adviser/cement/import-meta-env";
8
9
 
9
10
  export type EnvTuple = ([string, string] | [string, string][] | Record<string, string> | Iterator<[string, string]>)[];
10
11
 
@@ -22,6 +23,7 @@ export interface EnvActions extends EnvMap {
22
23
  export interface EnvFactoryOpts {
23
24
  readonly symbol: string; // default "CP_ENV" used by BrowserEnvActions
24
25
  readonly presetEnv: Map<string, string>;
26
+ testPatchImportMetaEnv?: Record<string, string>;
25
27
  readonly id: string; // to reinit in tests
26
28
  }
27
29
 
@@ -66,8 +68,11 @@ export function envFactory(opts: Partial<EnvFactoryOpts> = {}): Env {
66
68
  if (!found) {
67
69
  throw new Error("SysContainer:envFactory: no env available");
68
70
  }
71
+
72
+ testInjectImportMetaEnv(opts.testPatchImportMetaEnv);
73
+
69
74
  return _envFactories.get(opts.id ?? found.id).once(() => {
70
- const action = found.fn(opts);
75
+ const action = wrapImportMetaEnv(found.fn(opts));
71
76
  const ret = new EnvImpl(action, opts);
72
77
  action.register(ret);
73
78
  return ret;
@@ -12,20 +12,24 @@ export function stripper<T extends ArrayLike<S> | S, S>(
12
12
  }
13
13
  return s;
14
14
  });
15
- return localStripper(undefined, restrips, obj) as T extends ArrayLike<unknown>
15
+ const selfRef = new WeakSet<object>();
16
+ return localStripper(undefined, restrips, obj, selfRef) as T extends ArrayLike<unknown>
16
17
  ? Record<string, unknown>[]
17
18
  : Record<string, unknown>;
18
19
  }
19
20
 
20
- function localStripper<T>(path: string | undefined, restrips: RegExp[], obj: T): unknown {
21
+ function localStripper<T>(path: string | undefined, restrips: RegExp[], obj: T, selfRef: WeakSet<object>): unknown {
21
22
  if (typeof obj !== "object" || obj === null) {
22
23
  return obj;
23
24
  }
25
+ if (selfRef.has(obj)) {
26
+ return obj;
27
+ }
28
+ selfRef.add(obj);
24
29
  if (Array.isArray(obj)) {
25
- return obj.map((i) => localStripper(path, restrips, i));
30
+ return obj.map((i) => localStripper(path, restrips, i, selfRef));
26
31
  }
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- const ret = { ...obj } as Record<string, any>;
32
+ const ret = { ...obj } as Record<string, unknown>;
29
33
  const matcher = (key: string, nextPath: string): boolean => {
30
34
  for (const re of restrips) {
31
35
  if (re.test(key) || re.test(nextPath)) {
@@ -49,16 +53,15 @@ function localStripper<T>(path: string | undefined, restrips: RegExp[], obj: T):
49
53
  }
50
54
  if (typeof ret[key] === "object") {
51
55
  if (Array.isArray(ret[key])) {
52
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
53
56
  ret[key] = ret[key].reduce((acc: unknown[], v, i) => {
54
57
  const toDelete = matcher(key, `${nextPath}[${i}]`);
55
58
  if (!toDelete) {
56
- acc.push(localStripper(`${nextPath}[${i}]`, restrips, v));
59
+ acc.push(localStripper(`${nextPath}[${i}]`, restrips, v, selfRef));
57
60
  }
58
61
  return acc;
59
62
  }, []);
60
63
  } else {
61
- ret[key] = localStripper(nextPath, restrips, ret[key]);
64
+ ret[key] = localStripper(nextPath, restrips, ret[key], selfRef);
62
65
  }
63
66
  }
64
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"patch-version-cmd.d.ts","sourceRoot":"","sources":["../../../../src/cli/patch-version-cmd.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAmC,MAAM,QAAQ,CAAC;AAmDlE,wBAAgB,oBAAoB,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CAuCjE;AAmBD,wBAAgB,eAAe,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CA+B5D;AAYD,wBAAgB,gBAAgB,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CA6B7D;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFnH;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CA2C7D"}
1
+ {"version":3,"file":"patch-version-cmd.d.ts","sourceRoot":"","sources":["../../../../src/cli/patch-version-cmd.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAmC,MAAM,QAAQ,CAAC;AAkFlE,wBAAgB,oBAAoB,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CAajE;AAmBD,wBAAgB,eAAe,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CA+B5D;AAYD,wBAAgB,gBAAgB,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CA6B7D;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFnH;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC,CA2C7D"}