@nxtedition/lib 14.0.0-alpha.2 → 14.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "14.0.0-alpha.2",
3
+ "version": "14.0.1",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "files": [
@@ -22,7 +22,7 @@ module.exports = (options) => {
22
22
  try {
23
23
  return compileObjectTemplate(obj)(...args)
24
24
  } catch (err) {
25
- return rxjs.throwError(err)
25
+ return rxjs.throwError(() => err)
26
26
  }
27
27
  }
28
28
 
@@ -37,27 +37,25 @@ module.exports = (options) => {
37
37
  for (let i = 0; i < arr.length; i++) {
38
38
  const resolver = compileTemplateLazy(arr[i])
39
39
  if (resolver) {
40
- resolvers ??= []
40
+ resolvers ??= [() => rxjs.of({ indices, arr })]
41
41
  resolvers.push(resolver)
42
42
  indices ??= []
43
43
  indices.push(i)
44
44
  }
45
45
  }
46
46
 
47
- if (!resolvers) {
48
- return null
49
- }
50
-
51
- return (...args) =>
52
- rxjs.combineLatest(resolvers.map((resolver) => resolver(...args))).pipe(
53
- rx.map((values) => {
54
- const ret = [...arr]
55
- for (let n = 0; n < values.length; n++) {
56
- ret[indices[n]] = values[n]
57
- }
58
- return ret
59
- })
60
- )
47
+ return resolvers
48
+ ? (...args) =>
49
+ rxjs.combineLatest(resolvers.map((resolver) => resolver(...args))).pipe(
50
+ rx.map((values) => {
51
+ const ret = [...arr]
52
+ for (let n = 0; n < values.length; n++) {
53
+ ret[indices[n]] = values[n]
54
+ }
55
+ return ret
56
+ })
57
+ )
58
+ : null
61
59
  }
62
60
 
63
61
  const compileArrayTemplate = weakCache(function compileArrayTemplate(arr) {
@@ -84,20 +82,18 @@ module.exports = (options) => {
84
82
  }
85
83
  }
86
84
 
87
- if (!resolvers) {
88
- return null
89
- }
90
-
91
- return (...args) =>
92
- rxjs.combineLatest(resolvers.map((resolver) => resolver(...args))).pipe(
93
- rx.map((values) => {
94
- const ret = { ...obj }
95
- for (let n = 0; n < values.length; n++) {
96
- ret[indices[n]] = values[n]
97
- }
98
- return ret
99
- })
100
- )
85
+ return resolvers
86
+ ? (...args) =>
87
+ rxjs.combineLatest(resolvers.map((resolver) => resolver(...args))).pipe(
88
+ rx.map((values) => {
89
+ const ret = { ...obj }
90
+ for (let n = 0; n < values.length; n++) {
91
+ ret[indices[n]] = values[n]
92
+ }
93
+ return ret
94
+ })
95
+ )
96
+ : null
101
97
  }
102
98
 
103
99
  const compileObjectTemplate = weakCache(function compileObjectTemplate(obj) {
@@ -133,30 +129,27 @@ module.exports = (options) => {
133
129
  }
134
130
  }
135
131
 
136
- const _compileStringTemplate = weakCache(
137
- function _compileStringTemplate(match) {
138
- const { pre, type, body, post } = match
132
+ const _compileStringTemplate = weakCache(function _compileStringTemplate(str, match) {
133
+ const { pre, type, body, post } = match
139
134
 
140
- const compileExpression = compilers[type]
141
- if (!compileExpression) {
142
- throw new Error('unknown expression type')
143
- }
135
+ const compileExpression = compilers[type]
136
+ if (!compileExpression) {
137
+ throw new Error('unknown expression type: ' + type)
138
+ }
144
139
 
145
- const expr = compileExpression(body)
140
+ const expr = compileExpression(body)
146
141
 
147
- if (!pre && !post) {
148
- return expr
149
- }
142
+ if (!pre && !post) {
143
+ return expr
144
+ }
150
145
 
151
- return (...args) =>
152
- expr(...args).pipe(
153
- rx.switchMap((body) =>
154
- compileStringTemplate(`${pre}${stringify(body, type !== 'js')}${post}`)(...args)
155
- )
146
+ return (...args) =>
147
+ expr(...args).pipe(
148
+ rx.switchMap((body) =>
149
+ compileStringTemplate(`${pre}${stringify(body, type !== 'js')}${post}`)(...args)
156
150
  )
157
- },
158
- (match) => match.input
159
- )
151
+ )
152
+ })
160
153
 
161
154
  function compileStringTemplateLazy(str) {
162
155
  if (!fp.isString(str)) {
@@ -224,7 +217,7 @@ module.exports = (options) => {
224
217
  try {
225
218
  return compileTemplate(str)(...args)
226
219
  } catch (err) {
227
- return rxjs.throwError(err)
220
+ return rxjs.throwError(() => err)
228
221
  }
229
222
  }
230
223
 
@@ -141,6 +141,8 @@ function proxyify(value, expression) {
141
141
  }
142
142
  }
143
143
 
144
+ const MAP_POOL = []
145
+
144
146
  module.exports = ({ ds, ...options }) => {
145
147
  class Expression {
146
148
  constructor(context, script, expression, args, observer) {
@@ -151,7 +153,7 @@ module.exports = ({ ds, ...options }) => {
151
153
 
152
154
  // TODO (perf): This could be faster by using an array + indices.
153
155
  // A bit similar to how react-hooks works.
154
- this._entries = new Map()
156
+ this._entries = null
155
157
  this._refreshing = false
156
158
  this._counter = 0
157
159
  this._value = kEmpty
@@ -159,7 +161,7 @@ module.exports = ({ ds, ...options }) => {
159
161
  this._destroyed = false
160
162
  this._subscription = null
161
163
  this._args = null
162
- this._hasArgs = false
164
+ this._ready = false
163
165
  this._handler = {
164
166
  get: (target, prop) => proxyify(target[prop], this),
165
167
  }
@@ -169,16 +171,20 @@ module.exports = ({ ds, ...options }) => {
169
171
  this._subscription = args.subscribe({
170
172
  next: (args) => {
171
173
  this._args = this._proxify ? proxyify(args, this) : args
172
- this._hasArgs = true
174
+ this._ready = true
173
175
  this._refresh()
174
176
  },
175
177
  error: (err) => {
176
178
  this._observer.error(err)
179
+ this._subscription = null
180
+ },
181
+ complete: () => {
182
+ this._subscription = null
177
183
  },
178
184
  })
179
185
  } else {
180
186
  this._args = this._proxify ? proxyify(args, this) : args
181
- this._hasArgs = true
187
+ this._ready = true
182
188
  }
183
189
 
184
190
  this._refreshNT(this)
@@ -231,16 +237,25 @@ module.exports = ({ ds, ...options }) => {
231
237
  _destroy() {
232
238
  this._destroyed = true
233
239
  this._subscription?.unsubscribe()
234
- for (const entry of this._entries.values()) {
235
- entry.dispose()
240
+
241
+ if (this._entries) {
242
+ for (const entry of this._entries.values()) {
243
+ entry.dispose()
244
+ }
245
+ this._entries.clear()
246
+
247
+ if (MAP_POOL.length < 1024) {
248
+ MAP_POOL.push(this._entries)
249
+ }
250
+
251
+ this._entries = null
236
252
  }
237
- this._entries.clear()
238
253
  }
239
254
 
240
255
  _refreshNT(self) {
241
256
  self._refreshing = false
242
257
 
243
- if (self._destroyed || self._disposing || !self._hasArgs) {
258
+ if (self._destroyed || self._disposing || !self._ready) {
244
259
  return
245
260
  }
246
261
 
@@ -271,18 +286,29 @@ module.exports = ({ ds, ...options }) => {
271
286
  self._context.nxt = null
272
287
 
273
288
  self._disposing = true
274
- for (const entry of self._entries.values()) {
275
- if (entry.counter !== self._counter) {
276
- entry.dispose()
277
- self._entries.delete(entry.key)
289
+
290
+ if (self._entries) {
291
+ for (const entry of self._entries.values()) {
292
+ if (entry.counter !== self._counter) {
293
+ entry.dispose()
294
+ self._entries.delete(entry.key)
295
+ }
296
+ }
297
+ if (self._entries.size === 0) {
298
+ self._entries = null
278
299
  }
279
300
  }
301
+
302
+ if (!self._entries) {
303
+ self._args = null
304
+ }
305
+
280
306
  self._disposing = false
281
307
  }
282
308
  }
283
309
 
284
310
  _refresh = () => {
285
- if (this._refreshing || this._destroyed || this._disposing || !this._hasArgs) {
311
+ if (this._refreshing || this._destroyed || this._disposing || !this._ready) {
286
312
  return
287
313
  }
288
314
 
@@ -291,6 +317,7 @@ module.exports = ({ ds, ...options }) => {
291
317
  }
292
318
 
293
319
  _getEntry(key, Entry, opaque) {
320
+ this._entries ??= MAP_POOL.pop() ?? new Map()
294
321
  let entry = this._entries.get(key)
295
322
  if (!entry) {
296
323
  entry = new Entry(key, this._refresh, opaque)