@nxtedition/lib 26.8.8 → 27.0.0-alpha.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/app.js +1 -1
- package/couch.js +1 -1
- package/package.json +10 -48
- package/rxjs/auditMap.js +0 -111
- package/rxjs/auditMap.test.js +0 -64
- package/rxjs/combineMap.d.ts +0 -6
- package/rxjs/combineMap.js +0 -152
- package/rxjs/combineMap.test.js +0 -199
- package/rxjs/firstValueFrom.d.ts +0 -12
- package/rxjs/firstValueFrom.js +0 -18
- package/rxjs/lastValueFrom.js +0 -14
- package/rxjs/retry.js +0 -112
- package/rxjs/withAbortSignal.js +0 -31
- package/s3.js +0 -339
- package/timeline.js +0 -115
- package/util/template/index-common.d.ts +0 -67
- package/util/template/index-common.js +0 -226
- package/util/template/index-web.d.ts +0 -1
- package/util/template/index-web.js +0 -28
- package/util/template/index.d.ts +0 -1
- package/util/template/index.js +0 -26
- package/util/template/index.test.js +0 -94
- package/util/template/javascript.js +0 -692
- package/util/template/nextpressions.js +0 -600
- package/util/template/nextpressions.test.js +0 -165
- package/util/template/transform.js +0 -22
- package/util/template/transform.test.js +0 -16
- package/weakCache.d.ts +0 -4
- package/weakCache.js +0 -25
- package/yield.js +0 -103
|
@@ -1,692 +0,0 @@
|
|
|
1
|
-
import { makeWeakCache } from '../../weakCache.js'
|
|
2
|
-
import * as rxjs from 'rxjs'
|
|
3
|
-
import objectHash from 'object-hash'
|
|
4
|
-
import * as datefns from 'date-fns'
|
|
5
|
-
import JSON5 from 'json5'
|
|
6
|
-
import fp from 'lodash/fp.js'
|
|
7
|
-
import moment from 'moment-timezone'
|
|
8
|
-
import Timecode from 'smpte-timecode'
|
|
9
|
-
import transform from './transform.js'
|
|
10
|
-
import { doYield } from '../../yield.js'
|
|
11
|
-
|
|
12
|
-
const SEP = String.fromCharCode(30) // ASCII 1E
|
|
13
|
-
|
|
14
|
-
const kSuspend = Symbol('kSuspend')
|
|
15
|
-
const kEmpty = Symbol('kEmpty')
|
|
16
|
-
const maxInt = 2147483647
|
|
17
|
-
|
|
18
|
-
class TimerEntry {
|
|
19
|
-
constructor(key, refresh, delay) {
|
|
20
|
-
this.key = key
|
|
21
|
-
this.counter = -1
|
|
22
|
-
|
|
23
|
-
this.timer = setTimeout(refresh, delay)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
dispose() {
|
|
27
|
-
clearTimeout(this.timer)
|
|
28
|
-
this.timer = null
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class FetchEntry {
|
|
33
|
-
constructor(key, refresh, { resource, options, fetch }) {
|
|
34
|
-
this.key = key
|
|
35
|
-
this.counter = -1
|
|
36
|
-
this.ac = new AbortController()
|
|
37
|
-
|
|
38
|
-
this.refresh = refresh
|
|
39
|
-
this.body = null
|
|
40
|
-
this.status = null
|
|
41
|
-
this.error = null
|
|
42
|
-
|
|
43
|
-
let { headers, body, method } = options ?? {}
|
|
44
|
-
|
|
45
|
-
if (fp.isPlainObject(body) || fp.isArray(body)) {
|
|
46
|
-
headers = { 'content-type': 'application/json', ...headers }
|
|
47
|
-
body = JSON.stringify(body)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!method && body) {
|
|
51
|
-
method = 'POST'
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
fetch(resource, {
|
|
56
|
-
...options,
|
|
57
|
-
headers,
|
|
58
|
-
body,
|
|
59
|
-
signal: this.ac.signal,
|
|
60
|
-
})
|
|
61
|
-
.then(async (res) => {
|
|
62
|
-
// TODO (fix): Check cache-control and invalidate entry...
|
|
63
|
-
const body = await res.body.text()
|
|
64
|
-
if (this.refresh) {
|
|
65
|
-
// TODO (fix): max size...
|
|
66
|
-
this.status = res.statusCode
|
|
67
|
-
this.headers = res.headers
|
|
68
|
-
this.body = body
|
|
69
|
-
this.refresh()
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
.catch((err) => {
|
|
73
|
-
if (this.refresh) {
|
|
74
|
-
this.error = Object.assign(new Error('fetch failed'), {
|
|
75
|
-
data: { resource },
|
|
76
|
-
cause: err,
|
|
77
|
-
})
|
|
78
|
-
this.refresh()
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
} catch (err) {
|
|
82
|
-
this.error = Object.assign(new Error('fetch failed'), { data: { resource }, cause: err })
|
|
83
|
-
this.refresh()
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
dispose() {
|
|
88
|
-
this.refresh = null
|
|
89
|
-
|
|
90
|
-
this.ac.abort()
|
|
91
|
-
this.ac = null
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
class RecordEntry {
|
|
96
|
-
constructor(key, refresh, { name, path, ds, state }) {
|
|
97
|
-
if (state == null) {
|
|
98
|
-
state =
|
|
99
|
-
name.startsWith('{') || name.includes('?')
|
|
100
|
-
? ds.record.STATE.PROVIDER
|
|
101
|
-
: ds.record.STATE.SERVER
|
|
102
|
-
} else if (typeof state === 'string') {
|
|
103
|
-
state = ds.record.STATE[state.toUpperCase()] ?? ds.record.STATE.SERVER
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
this.key = key
|
|
107
|
-
this.counter = -1
|
|
108
|
-
|
|
109
|
-
this.record = ds.record.getRecord(name)
|
|
110
|
-
|
|
111
|
-
this.data = this.record.get(path)
|
|
112
|
-
this.ready = this.record.state >= state
|
|
113
|
-
this.refresh = () => {
|
|
114
|
-
const data = this.record.get(path)
|
|
115
|
-
const ready = this.record.state >= state
|
|
116
|
-
|
|
117
|
-
if (data !== this.data || ready !== this.ready) {
|
|
118
|
-
this.data = data
|
|
119
|
-
this.ready = ready
|
|
120
|
-
refresh()
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (this.record.subscribe) {
|
|
125
|
-
this.record.subscribe(this.refresh)
|
|
126
|
-
} else {
|
|
127
|
-
this.record.on('update', this.refresh)
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
dispose() {
|
|
132
|
-
this.record.unref()
|
|
133
|
-
if (this.record.unsubscribe) {
|
|
134
|
-
this.record.unsubscribe(this.refresh)
|
|
135
|
-
} else {
|
|
136
|
-
this.record.off('update', this.refresh)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
this.record = null
|
|
140
|
-
this.refresh = null
|
|
141
|
-
this.data = null
|
|
142
|
-
this.ready = false
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
class ObservableEntry {
|
|
147
|
-
constructor(key, refresh, observable) {
|
|
148
|
-
this.key = key
|
|
149
|
-
this.counter = -1
|
|
150
|
-
this.value = kEmpty
|
|
151
|
-
this.error = null
|
|
152
|
-
this.refresh = refresh
|
|
153
|
-
this.sync = true
|
|
154
|
-
this.subscription = observable.subscribe({
|
|
155
|
-
next: (value) => {
|
|
156
|
-
this.value = value
|
|
157
|
-
if (!this.sync) {
|
|
158
|
-
this.refresh()
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
error: (err) => {
|
|
162
|
-
this.error = err
|
|
163
|
-
if (!this.sync) {
|
|
164
|
-
this.refresh()
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
})
|
|
168
|
-
this.sync = false
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
dispose() {
|
|
172
|
-
this.subscription.unsubscribe()
|
|
173
|
-
this.subscription = null
|
|
174
|
-
this.refresh = null
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
class PromiseEntry {
|
|
179
|
-
constructor(key, refresh, promise) {
|
|
180
|
-
this.key = key
|
|
181
|
-
this.counter = -1
|
|
182
|
-
this.value = kEmpty
|
|
183
|
-
this.error = null
|
|
184
|
-
this.refresh = refresh
|
|
185
|
-
|
|
186
|
-
promise.then(
|
|
187
|
-
(value) => {
|
|
188
|
-
if (this.refresh) {
|
|
189
|
-
this.value = value
|
|
190
|
-
this.refresh()
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
(err) => {
|
|
194
|
-
if (this.refresh) {
|
|
195
|
-
this.error = err
|
|
196
|
-
this.refresh()
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
dispose() {
|
|
203
|
-
this.refresh = null
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function proxify(value, expression, handler, suspend = true) {
|
|
208
|
-
if (!expression) {
|
|
209
|
-
throw new Error('expression is not defined')
|
|
210
|
-
}
|
|
211
|
-
if (!handler) {
|
|
212
|
-
throw new Error('handler is not defined')
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (!value) {
|
|
216
|
-
return value
|
|
217
|
-
} else if (rxjs.isObservable(value)) {
|
|
218
|
-
return proxify(expression.observe(value, suspend), expression, handler, suspend)
|
|
219
|
-
} else if (typeof value?.then === 'function') {
|
|
220
|
-
return proxify(expression.wait(value, suspend), expression, handler, suspend)
|
|
221
|
-
} else if (typeof value === 'object') {
|
|
222
|
-
return new Proxy(value, handler)
|
|
223
|
-
} else {
|
|
224
|
-
return value
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function makeWrapper(expression) {
|
|
229
|
-
const handler = {
|
|
230
|
-
get: (target, prop) => proxify(target[prop], expression, handler),
|
|
231
|
-
}
|
|
232
|
-
return (value, suspend = true) => proxify(value, expression, handler, suspend)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export default function ({ ds, proxify, compiler, logger, platform }) {
|
|
236
|
-
const schedule = platform?.schedule ?? doYield
|
|
237
|
-
|
|
238
|
-
class Expression {
|
|
239
|
-
constructor(script, expression, args, observer) {
|
|
240
|
-
this._expression = expression
|
|
241
|
-
this._observer = observer
|
|
242
|
-
this._script = script
|
|
243
|
-
|
|
244
|
-
// TODO (perf): This could be faster by using an array + indices.
|
|
245
|
-
// A bit similar to how react-hooks works.
|
|
246
|
-
this._entries = new Map()
|
|
247
|
-
this._refreshing = false
|
|
248
|
-
this._counter = 0
|
|
249
|
-
this._value = kEmpty
|
|
250
|
-
this._disposing = false
|
|
251
|
-
this._destroyed = false
|
|
252
|
-
this._subscription = null
|
|
253
|
-
this._args = kEmpty
|
|
254
|
-
this._wrap = null
|
|
255
|
-
this._suspended = false
|
|
256
|
-
this._errored = false
|
|
257
|
-
this._globalThis = {
|
|
258
|
-
fp: null,
|
|
259
|
-
moment: null,
|
|
260
|
-
Timecode: null,
|
|
261
|
-
datefns: null,
|
|
262
|
-
JSON5: null,
|
|
263
|
-
$: null,
|
|
264
|
-
nxt: null,
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (rxjs.isObservable(args)) {
|
|
268
|
-
this._subscription = args.subscribe({
|
|
269
|
-
next: (args) => {
|
|
270
|
-
this._args = proxify ? this.wrap(args) : args
|
|
271
|
-
this._refresh()
|
|
272
|
-
},
|
|
273
|
-
error: (err) => {
|
|
274
|
-
this._observer.error(err)
|
|
275
|
-
},
|
|
276
|
-
})
|
|
277
|
-
} else {
|
|
278
|
-
this._args = proxify ? this.wrap(args) : args
|
|
279
|
-
this._refresh()
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
wrap(value, suspend = true) {
|
|
284
|
-
this._wrap ??= makeWrapper(this)
|
|
285
|
-
return this._wrap(value, suspend)
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
suspend() {
|
|
289
|
-
throw kSuspend
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
fetch(resource, options, suspend) {
|
|
293
|
-
return this._getFetch(resource, options, suspend)
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
observe(observable, suspend) {
|
|
297
|
-
return this._getObservable(observable, suspend)
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
then(promise, suspend) {
|
|
301
|
-
return this._getPromise(promise, suspend)
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/** @deprecated */
|
|
305
|
-
ds(name, state, suspend) {
|
|
306
|
-
return !name || typeof name !== 'string'
|
|
307
|
-
? ds.record.JSON.EMPTY_OBJ
|
|
308
|
-
: this._getRecord(name, null, state, suspend)
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
get(name, path, state, suspend) {
|
|
312
|
-
return !name || typeof name !== 'string'
|
|
313
|
-
? path
|
|
314
|
-
? undefined
|
|
315
|
-
: ds.record.JSON.EMPTY_OBJ
|
|
316
|
-
: this._getRecord(name, path, state, suspend)
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
timer(dueTime, dueValue = dueTime, suspend) {
|
|
320
|
-
return this._getTimer(dueTime, dueValue, suspend)
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
asset(id, type, state, suspend) {
|
|
324
|
-
return this._getHasRawAssetType(id, type, state, suspend)
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
hash(value) {
|
|
328
|
-
return objectHash(value)
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/** @deprecated */
|
|
332
|
-
_ds(name, postfix, state, suspend) {
|
|
333
|
-
return !name || typeof name !== 'string'
|
|
334
|
-
? ds.record.JSON.EMPTY_OBJ
|
|
335
|
-
: this._getRecord(postfix ? name + postfix : name, null, state, suspend)
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
_get(name, postfix, path, state, suspend) {
|
|
339
|
-
return !name || typeof name !== 'string'
|
|
340
|
-
? path
|
|
341
|
-
? undefined
|
|
342
|
-
: ds.record.JSON.EMPTY_OBJ
|
|
343
|
-
: this._getRecord(postfix ? name + postfix : name, path, state, suspend)
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
_asset(id, type, state, suspend) {
|
|
347
|
-
if (!type || typeof type !== 'string') {
|
|
348
|
-
throw new Error(`invalid argument: type (${type})`)
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return !id || typeof id !== 'string'
|
|
352
|
-
? null
|
|
353
|
-
: this._getHasRawAssetType(id, type, state, suspend)
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
_destroy() {
|
|
357
|
-
this._destroyed = true
|
|
358
|
-
this._subscription?.unsubscribe()
|
|
359
|
-
|
|
360
|
-
for (const entry of this._entries.values()) {
|
|
361
|
-
entry.dispose()
|
|
362
|
-
}
|
|
363
|
-
this._entries.clear()
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
_refreshImpl = () => {
|
|
367
|
-
this._refreshing = false
|
|
368
|
-
|
|
369
|
-
if (this._destroyed || this._disposing || this._args === kEmpty) {
|
|
370
|
-
return
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
this._counter = (this._counter + 1) & maxInt
|
|
374
|
-
|
|
375
|
-
const previous = compiler.current
|
|
376
|
-
compiler.current = this
|
|
377
|
-
|
|
378
|
-
try {
|
|
379
|
-
if (this._suspended !== false) {
|
|
380
|
-
throw new Error('expression is already suspended')
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
this._globalThis.fp = globalThis.fp
|
|
384
|
-
this._globalThis.moment = globalThis.moment
|
|
385
|
-
this._globalThis.Timecode = globalThis.Timecode
|
|
386
|
-
this._globalThis.datefns = globalThis.datefns
|
|
387
|
-
this._globalThis.JSON5 = globalThis.JSON5
|
|
388
|
-
this._globalThis.$ = globalThis.$
|
|
389
|
-
this._globalThis.nxt = globalThis.nxt
|
|
390
|
-
|
|
391
|
-
let value
|
|
392
|
-
try {
|
|
393
|
-
globalThis.fp = fp
|
|
394
|
-
globalThis.moment = moment
|
|
395
|
-
globalThis.Timecode = Timecode
|
|
396
|
-
globalThis.datefns = datefns
|
|
397
|
-
globalThis.JSON5 = JSON5
|
|
398
|
-
globalThis.$ = this._args
|
|
399
|
-
globalThis.nxt = this
|
|
400
|
-
|
|
401
|
-
// TODO (fix): This should be sandboxed somehow...
|
|
402
|
-
// - Use a webworker?
|
|
403
|
-
// - Use vm for Node only?
|
|
404
|
-
// - Use https://github.com/tc39/proposal-shadowrealm?
|
|
405
|
-
value = this._script()
|
|
406
|
-
} finally {
|
|
407
|
-
globalThis.fp = this._globalThis.fp
|
|
408
|
-
globalThis.moment = this._globalThis.moment
|
|
409
|
-
globalThis.Timecode = this._globalThis.Timecode
|
|
410
|
-
globalThis.datefns = this._globalThis.datefns
|
|
411
|
-
globalThis.JSON5 = this._globalThis.JSON5
|
|
412
|
-
globalThis.$ = this._globalThis.$
|
|
413
|
-
globalThis.nxt = this._globalThis.nxt
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
this._errored = false
|
|
417
|
-
if (this._suspended) {
|
|
418
|
-
return
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
if (value !== this._value) {
|
|
422
|
-
this._value = value
|
|
423
|
-
this._observer.next(value)
|
|
424
|
-
}
|
|
425
|
-
} catch (err) {
|
|
426
|
-
if (err === kSuspend) {
|
|
427
|
-
return
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
this._errored = true
|
|
431
|
-
|
|
432
|
-
const error = Object.assign(new Error('expression failed'), {
|
|
433
|
-
cause: err,
|
|
434
|
-
data: { expression: this._expression, data: this._args },
|
|
435
|
-
})
|
|
436
|
-
|
|
437
|
-
if (this._suspended) {
|
|
438
|
-
if (logger) {
|
|
439
|
-
logger.error({ err: error })
|
|
440
|
-
} else {
|
|
441
|
-
process.emitWarning(error)
|
|
442
|
-
}
|
|
443
|
-
} else {
|
|
444
|
-
this._observer.error(error)
|
|
445
|
-
}
|
|
446
|
-
} finally {
|
|
447
|
-
compiler.current = previous
|
|
448
|
-
|
|
449
|
-
this._suspended = false
|
|
450
|
-
this._disposing = true
|
|
451
|
-
|
|
452
|
-
for (const entry of this._entries.values()) {
|
|
453
|
-
if (entry.counter !== this._counter) {
|
|
454
|
-
entry.dispose()
|
|
455
|
-
this._entries.delete(entry.key)
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// TODO (perf): Make this work.
|
|
460
|
-
// if (!this._entries) {
|
|
461
|
-
// this._args = null
|
|
462
|
-
// }
|
|
463
|
-
|
|
464
|
-
this._disposing = false
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
_refresh = () => {
|
|
469
|
-
if (this._refreshing || this._destroyed || this._disposing || this._args === kEmpty) {
|
|
470
|
-
return
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
this._refreshing = true
|
|
474
|
-
schedule(this._refreshImpl)
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
_getEntry(key, Entry, opaque) {
|
|
478
|
-
let entry = this._entries.get(key)
|
|
479
|
-
if (!entry) {
|
|
480
|
-
entry = new Entry(key, this._refresh, opaque)
|
|
481
|
-
this._entries.set(key, entry)
|
|
482
|
-
}
|
|
483
|
-
entry.counter = this._counter
|
|
484
|
-
return entry
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
_getFetch(resource, options, suspend) {
|
|
488
|
-
const key = JSON.stringify({ resource, options })
|
|
489
|
-
const entry = this._getEntry(key, FetchEntry, { resource, options, fetch: platform.fetch })
|
|
490
|
-
|
|
491
|
-
if (entry.refresh === null) {
|
|
492
|
-
return null
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
if (entry.error) {
|
|
496
|
-
throw entry.error
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
if (!entry.status) {
|
|
500
|
-
this._suspended = true
|
|
501
|
-
if (suspend ?? this._errored) {
|
|
502
|
-
throw kSuspend
|
|
503
|
-
} else {
|
|
504
|
-
return null
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
return { status: entry.status, headers: entry.headers, body: entry.body }
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
_getObservable(observable, suspend) {
|
|
512
|
-
if (!rxjs.isObservable(observable)) {
|
|
513
|
-
throw new Error(`invalid argument: observable (${observable})`)
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
const entry = this._getEntry(observable, ObservableEntry, observable)
|
|
517
|
-
|
|
518
|
-
if (entry.refresh === null) {
|
|
519
|
-
return null
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
if (entry.error) {
|
|
523
|
-
throw entry.error
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
if (entry.value === kEmpty) {
|
|
527
|
-
this._suspended = true
|
|
528
|
-
if (suspend ?? this._errored) {
|
|
529
|
-
throw kSuspend
|
|
530
|
-
} else {
|
|
531
|
-
return null
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
return entry.value
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
_getPromise(promise, suspend) {
|
|
539
|
-
if (typeof promise?.then !== 'function') {
|
|
540
|
-
throw new Error(`invalid argument: Promise (${promise})`)
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
const entry = this._getEntry(promise, PromiseEntry, promise)
|
|
544
|
-
|
|
545
|
-
if (entry.refresh === null) {
|
|
546
|
-
return null
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
if (entry.error) {
|
|
550
|
-
throw entry.error
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if (entry.value === kEmpty) {
|
|
554
|
-
this._suspended = true
|
|
555
|
-
if (suspend ?? this._errored) {
|
|
556
|
-
throw kSuspend
|
|
557
|
-
} else {
|
|
558
|
-
return null
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
return entry.value
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
_getTimer(dueTime, dueValue = dueTime, suspend) {
|
|
566
|
-
const key = JSON.stringify({ dueTime, dueValue })
|
|
567
|
-
|
|
568
|
-
dueTime = Number.isFinite(dueTime) ? dueTime : new Date(dueTime).valueOf()
|
|
569
|
-
|
|
570
|
-
const delay = dueTime - Date.now()
|
|
571
|
-
|
|
572
|
-
if (Number.isFinite(dueTime) && delay > 0 && delay < 2 ** 31 - 1) {
|
|
573
|
-
this._getEntry(key, TimerEntry, delay)
|
|
574
|
-
if (suspend ?? this._errored) {
|
|
575
|
-
throw kSuspend
|
|
576
|
-
} else {
|
|
577
|
-
return null
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
return dueValue
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
_getRecord(name, path, state, suspend) {
|
|
585
|
-
if (name != null && typeof name !== 'string') {
|
|
586
|
-
throw new Error(`invalid argument: key (${name})`)
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
if (path != null && typeof path !== 'string') {
|
|
590
|
-
throw new Error(`invalid argument: path (${path})`)
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
if (state != null && typeof state !== 'string' && typeof state !== 'number') {
|
|
594
|
-
throw new Error(`invalid argument: state (${state})`)
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
if (typeof state === 'string') {
|
|
598
|
-
state = ds.record.STATE[state.toUpperCase()]
|
|
599
|
-
} else if (state == null) {
|
|
600
|
-
state = ds.record.STATE.SERVER
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
const key = '' + (name ?? '') + SEP + (path ?? '') + SEP + (state ?? '')
|
|
604
|
-
const entry = this._getEntry(key, RecordEntry, { ds, name, path, state })
|
|
605
|
-
|
|
606
|
-
if (!entry.ready) {
|
|
607
|
-
this._suspended = true
|
|
608
|
-
if (suspend ?? this._errored) {
|
|
609
|
-
throw kSuspend
|
|
610
|
-
} else {
|
|
611
|
-
return entry.data
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
return entry.data
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
_getHasRawAssetType(id, type, state, suspend) {
|
|
619
|
-
if (!id || typeof id !== 'string') {
|
|
620
|
-
throw new Error(`invalid argument: id (${id})`)
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
if (!type || typeof type !== 'string') {
|
|
624
|
-
throw new Error(`invalid argument: type (${type})`)
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
const rawTypes = this._getRecord(
|
|
628
|
-
id + ':asset.rawTypes?',
|
|
629
|
-
'value',
|
|
630
|
-
state ?? ds.record.PROVIDER,
|
|
631
|
-
suspend,
|
|
632
|
-
)
|
|
633
|
-
return Array.isArray(rawTypes) && rawTypes.includes(type) ? id : null
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
return makeWeakCache((expression) => {
|
|
638
|
-
let script
|
|
639
|
-
try {
|
|
640
|
-
script = new Function(
|
|
641
|
-
transform(`
|
|
642
|
-
const _ = (value, ...fns) => {
|
|
643
|
-
if (value == null) {
|
|
644
|
-
return value
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
for (const fn of fns) {
|
|
648
|
-
value = fn(value)
|
|
649
|
-
if (value == null) {
|
|
650
|
-
return value
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
return value
|
|
655
|
-
};
|
|
656
|
-
|
|
657
|
-
const fp = globalThis.fp
|
|
658
|
-
const moment = globalThis.moment
|
|
659
|
-
const Timecode = globalThis.Timecode
|
|
660
|
-
const datefns = globalThis.datefns
|
|
661
|
-
const JSON5 = globalThis.JSON5
|
|
662
|
-
const $ = globalThis.$
|
|
663
|
-
const nxt = globalThis.nxt
|
|
664
|
-
|
|
665
|
-
_.asset = (type, state, suspend) => (name) => nxt._asset(name, type, state, suspend);
|
|
666
|
-
_.ds = (postfix, state, suspend) => (name) => nxt._ds(name, postfix, state, suspend);
|
|
667
|
-
_.get = (postfix, path, state, suspend) => (name) => nxt._get(name, postfix, path, state, suspend);
|
|
668
|
-
_.timer = (dueTime) => (dueValue) => nxt.timer(dueTime, dueValue);
|
|
669
|
-
_.fetch = (options, suspend) => (resource) => nxt.fetch(resource, options, suspend);
|
|
670
|
-
${expression}
|
|
671
|
-
`),
|
|
672
|
-
)
|
|
673
|
-
} catch (err) {
|
|
674
|
-
return () =>
|
|
675
|
-
rxjs.throwError(
|
|
676
|
-
Object.assign(new Error(`failed to parse expression ${expression}`), { cause: err }),
|
|
677
|
-
)
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
return (args) =>
|
|
681
|
-
new rxjs.Observable((o) => {
|
|
682
|
-
try {
|
|
683
|
-
const exp = new Expression(script, expression, args, o)
|
|
684
|
-
return () => {
|
|
685
|
-
exp._destroy()
|
|
686
|
-
}
|
|
687
|
-
} catch (err) {
|
|
688
|
-
o.error(err)
|
|
689
|
-
}
|
|
690
|
-
})
|
|
691
|
-
})
|
|
692
|
-
}
|