@nxtedition/lib 14.0.11 → 14.0.13
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 +1 -1
- package/util/template/index.js +99 -146
- package/util/template/javascript.js +92 -24
package/package.json
CHANGED
package/util/template/index.js
CHANGED
|
@@ -7,10 +7,14 @@ const JSON5 = require('json5')
|
|
|
7
7
|
const objectHash = require('object-hash')
|
|
8
8
|
const weakCache = require('../../weakCache')
|
|
9
9
|
|
|
10
|
-
module.exports = (
|
|
10
|
+
module.exports = ({ ds, proxify }) => {
|
|
11
|
+
const compiler = {
|
|
12
|
+
current: null,
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
const compilers = {
|
|
12
|
-
nxt: getNxtpressionsCompiler(
|
|
13
|
-
js: getJavascriptCompiler(
|
|
16
|
+
nxt: getNxtpressionsCompiler({ ds }),
|
|
17
|
+
js: getJavascriptCompiler({ ds, proxify, compiler }),
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
function inner(str) {
|
|
@@ -70,158 +74,99 @@ module.exports = (options) => {
|
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
77
|
+
function compileArrayTemplate(template) {
|
|
78
|
+
let resolvers
|
|
79
|
+
let indices
|
|
80
|
+
|
|
81
|
+
for (let i = 0; i < template.length; i++) {
|
|
82
|
+
const resolver = compileTemplate(template[i])
|
|
83
|
+
if (resolver) {
|
|
84
|
+
resolvers ??= []
|
|
85
|
+
resolvers.push(resolver)
|
|
86
|
+
indices ??= []
|
|
87
|
+
indices.push(i)
|
|
81
88
|
}
|
|
89
|
+
}
|
|
82
90
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
resolvers ??= []
|
|
90
|
-
resolvers.push(resolver)
|
|
91
|
-
indices ??= []
|
|
92
|
-
indices.push(i)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return resolvers
|
|
97
|
-
? (arr, args$) => {
|
|
98
|
-
const len = resolvers.length
|
|
99
|
-
const values = new Array(len)
|
|
100
|
-
for (let n = 0; n < len; n++) {
|
|
101
|
-
values[n] = resolvers[n](arr[indices[n]], args$)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return rxjs.combineLatest(values).pipe(
|
|
105
|
-
rx.map((values) => {
|
|
106
|
-
const ret = [...arr]
|
|
107
|
-
for (let n = 0; n < values.length; n++) {
|
|
108
|
-
ret[indices[n]] = values[n]
|
|
109
|
-
}
|
|
110
|
-
return ret
|
|
111
|
-
})
|
|
112
|
-
)
|
|
91
|
+
return resolvers
|
|
92
|
+
? (arr, args$) => {
|
|
93
|
+
const len = resolvers.length
|
|
94
|
+
const values = new Array(len)
|
|
95
|
+
for (let n = 0; n < len; n++) {
|
|
96
|
+
values[n] = resolvers[n](arr[indices[n]], args$)
|
|
113
97
|
}
|
|
114
|
-
: null
|
|
115
|
-
},
|
|
116
|
-
(arr, hash) => hash ?? hashTemplate(arr)
|
|
117
|
-
)
|
|
118
98
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
99
|
+
return rxjs.combineLatest(values).pipe(
|
|
100
|
+
rx.map((values) => {
|
|
101
|
+
const ret = [...arr]
|
|
102
|
+
for (let n = 0; n < values.length; n++) {
|
|
103
|
+
ret[indices[n]] = values[n]
|
|
104
|
+
}
|
|
105
|
+
return ret
|
|
106
|
+
})
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
: null
|
|
125
110
|
}
|
|
126
111
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
throw new Error('invalid argument')
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (!hash) {
|
|
134
|
-
return null
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
let resolvers
|
|
138
|
-
let indices
|
|
112
|
+
function compileObjectTemplate(template) {
|
|
113
|
+
let resolvers
|
|
114
|
+
let indices
|
|
139
115
|
|
|
140
|
-
|
|
116
|
+
const keys = Object.keys(template)
|
|
141
117
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
118
|
+
for (let i = 0; i < keys.length; i++) {
|
|
119
|
+
const resolver = compileTemplate(template[keys[i]])
|
|
120
|
+
if (resolver) {
|
|
121
|
+
resolvers ??= []
|
|
122
|
+
resolvers.push(resolver)
|
|
123
|
+
indices ??= []
|
|
124
|
+
indices.push(keys[i])
|
|
150
125
|
}
|
|
126
|
+
}
|
|
151
127
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return rxjs.combineLatest(values).pipe(
|
|
161
|
-
rx.map((values) => {
|
|
162
|
-
const ret = { ...obj }
|
|
163
|
-
for (let n = 0; n < values.length; n++) {
|
|
164
|
-
ret[indices[n]] = values[n]
|
|
165
|
-
}
|
|
166
|
-
return ret
|
|
167
|
-
})
|
|
168
|
-
)
|
|
128
|
+
return resolvers
|
|
129
|
+
? (obj, args$) => {
|
|
130
|
+
const len = resolvers.length
|
|
131
|
+
const values = new Array(len)
|
|
132
|
+
for (let n = 0; n < len; n++) {
|
|
133
|
+
values[n] = resolvers[n](obj[indices[n]], args$)
|
|
169
134
|
}
|
|
170
|
-
: null
|
|
171
|
-
},
|
|
172
|
-
(obj, hash) => hash ?? hashTemplate(obj)
|
|
173
|
-
)
|
|
174
135
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
136
|
+
return rxjs.combineLatest(values).pipe(
|
|
137
|
+
rx.map((values) => {
|
|
138
|
+
const ret = { ...obj }
|
|
139
|
+
for (let n = 0; n < values.length; n++) {
|
|
140
|
+
ret[indices[n]] = values[n]
|
|
141
|
+
}
|
|
142
|
+
return ret
|
|
143
|
+
})
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
: null
|
|
182
147
|
}
|
|
183
148
|
|
|
184
|
-
|
|
185
|
-
(template
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (!hash) {
|
|
191
|
-
return null
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const match = inner(template)
|
|
195
|
-
if (!match) {
|
|
196
|
-
return null
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const { pre, type, body, post } = match
|
|
200
|
-
|
|
201
|
-
const compileExpression = compilers[type]
|
|
202
|
-
if (!compileExpression) {
|
|
203
|
-
throw new Error('unknown expression type: ' + type)
|
|
204
|
-
}
|
|
149
|
+
function compileStringTemplate(template) {
|
|
150
|
+
const match = inner(template)
|
|
151
|
+
if (!match) {
|
|
152
|
+
return null
|
|
153
|
+
}
|
|
205
154
|
|
|
206
|
-
|
|
155
|
+
const { pre, type, body, post } = match
|
|
207
156
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
157
|
+
const compileExpression = compilers[type]
|
|
158
|
+
if (!compileExpression) {
|
|
159
|
+
throw new Error('unknown expression type: ' + type)
|
|
160
|
+
}
|
|
211
161
|
|
|
212
|
-
|
|
213
|
-
expr(args$).pipe(rx.map((body) => `${pre}${stringify(body, type !== 'js')}${post}`))
|
|
214
|
-
},
|
|
215
|
-
(str, hash) => hash ?? hashTemplate(str)
|
|
216
|
-
)
|
|
162
|
+
const expr = compileExpression(body)
|
|
217
163
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
throw new Error('invalid argument')
|
|
164
|
+
if (!pre && !post) {
|
|
165
|
+
return (str, args$) => expr(args$)
|
|
221
166
|
}
|
|
222
167
|
|
|
223
|
-
|
|
224
|
-
|
|
168
|
+
return (str, args$) =>
|
|
169
|
+
expr(args$).pipe(rx.map((body) => `${pre}${stringify(body, type !== 'js')}${post}`))
|
|
225
170
|
}
|
|
226
171
|
|
|
227
172
|
function stringify(value, escape) {
|
|
@@ -239,16 +184,24 @@ module.exports = (options) => {
|
|
|
239
184
|
return typeof val === 'string' && val.indexOf('{{') !== -1
|
|
240
185
|
}
|
|
241
186
|
|
|
187
|
+
const compileTemplateCache = weakCache(
|
|
188
|
+
(template) => {
|
|
189
|
+
if (fp.isPlainObject(template)) {
|
|
190
|
+
return compileObjectTemplate(template)
|
|
191
|
+
} else if (fp.isArray(template)) {
|
|
192
|
+
return compileArrayTemplate(template)
|
|
193
|
+
} else if (isTemplate(template)) {
|
|
194
|
+
return compileStringTemplate(template)
|
|
195
|
+
} else {
|
|
196
|
+
return null
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
(template, hash) => hash
|
|
200
|
+
)
|
|
201
|
+
|
|
242
202
|
function compileTemplate(template) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
} else if (fp.isArray(template)) {
|
|
246
|
-
return compileArrayTemplate(template)
|
|
247
|
-
} else if (isTemplate(template)) {
|
|
248
|
-
return compileStringTemplate(template)
|
|
249
|
-
} else {
|
|
250
|
-
return null
|
|
251
|
-
}
|
|
203
|
+
const hash = hashTemplate(template)
|
|
204
|
+
return hash ? compileTemplateCache(template, hash) : null
|
|
252
205
|
}
|
|
253
206
|
|
|
254
207
|
async function resolveTemplate(template, args$) {
|
|
@@ -263,10 +216,10 @@ module.exports = (options) => {
|
|
|
263
216
|
}
|
|
264
217
|
}
|
|
265
218
|
|
|
266
|
-
return {
|
|
219
|
+
return Object.assign(compiler, {
|
|
267
220
|
resolveTemplate,
|
|
268
221
|
onResolveTemplate,
|
|
269
222
|
compileTemplate,
|
|
270
223
|
isTemplate,
|
|
271
|
-
}
|
|
224
|
+
})
|
|
272
225
|
}
|
|
@@ -14,13 +14,13 @@ class TimerEntry {
|
|
|
14
14
|
constructor(key, refresh, delay) {
|
|
15
15
|
this.key = key
|
|
16
16
|
this.counter = null
|
|
17
|
+
|
|
17
18
|
this.timer = setTimeout(refresh, delay)
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
dispose() {
|
|
21
22
|
clearTimeout(this.timer)
|
|
22
23
|
|
|
23
|
-
this.refresh = null
|
|
24
24
|
this.timer = null
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -29,12 +29,12 @@ class FetchEntry {
|
|
|
29
29
|
constructor(key, refresh, { resource, options }) {
|
|
30
30
|
this.key = key
|
|
31
31
|
this.counter = null
|
|
32
|
+
|
|
32
33
|
this.refresh = refresh
|
|
33
34
|
this.ac = new AbortController()
|
|
34
35
|
this.signal = this.ac.signal
|
|
35
36
|
this.body = null
|
|
36
37
|
this.status = null
|
|
37
|
-
this.options = options
|
|
38
38
|
this.error = null
|
|
39
39
|
|
|
40
40
|
// TODO (fix): options.signal
|
|
@@ -42,9 +42,9 @@ class FetchEntry {
|
|
|
42
42
|
// TODO (fix): expire...
|
|
43
43
|
|
|
44
44
|
undici
|
|
45
|
-
.fetch(resource, { ...
|
|
45
|
+
.fetch(resource, { ...options, signal: this.signal })
|
|
46
46
|
.then(async (res) => {
|
|
47
|
-
if (
|
|
47
|
+
if (this.refresh) {
|
|
48
48
|
// TODO (fix): max size...
|
|
49
49
|
this.body = Buffer.from(await res.arrayBuffer())
|
|
50
50
|
this.status = res.status
|
|
@@ -53,7 +53,7 @@ class FetchEntry {
|
|
|
53
53
|
}
|
|
54
54
|
})
|
|
55
55
|
.catch((err) => {
|
|
56
|
-
if (
|
|
56
|
+
if (this.refresh) {
|
|
57
57
|
this.error = err
|
|
58
58
|
this.refresh()
|
|
59
59
|
}
|
|
@@ -61,9 +61,10 @@ class FetchEntry {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
dispose() {
|
|
64
|
-
this.ac.abort()
|
|
65
|
-
|
|
66
64
|
this.refresh = null
|
|
65
|
+
|
|
66
|
+
this.ac.abort()
|
|
67
|
+
this.ac = null
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -71,6 +72,7 @@ class RecordEntry {
|
|
|
71
72
|
constructor(key, refresh, ds) {
|
|
72
73
|
this.key = key
|
|
73
74
|
this.counter = null
|
|
75
|
+
|
|
74
76
|
this.refresh = refresh
|
|
75
77
|
this.record = ds.record.getRecord(key)
|
|
76
78
|
|
|
@@ -116,6 +118,36 @@ class ObservableEntry {
|
|
|
116
118
|
dispose() {
|
|
117
119
|
this.subscription.unsubscribe()
|
|
118
120
|
this.subscription = null
|
|
121
|
+
this.refresh = null
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
class PromiseEntry {
|
|
126
|
+
constructor(key, refresh, promise) {
|
|
127
|
+
this.key = key
|
|
128
|
+
this.counter = null
|
|
129
|
+
this.value = kEmpty
|
|
130
|
+
this.error = null
|
|
131
|
+
this.refresh = refresh
|
|
132
|
+
|
|
133
|
+
promise.then(
|
|
134
|
+
(value) => {
|
|
135
|
+
if (this.refresh) {
|
|
136
|
+
this.value = value
|
|
137
|
+
this.refresh()
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
(err) => {
|
|
141
|
+
if (this.refresh) {
|
|
142
|
+
this.error = err
|
|
143
|
+
this.refresh()
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
dispose() {
|
|
150
|
+
this.refresh = null
|
|
119
151
|
}
|
|
120
152
|
}
|
|
121
153
|
|
|
@@ -141,13 +173,15 @@ const globals = {
|
|
|
141
173
|
nxt: null,
|
|
142
174
|
}
|
|
143
175
|
|
|
144
|
-
function
|
|
176
|
+
function proxify(value, expression, handler) {
|
|
145
177
|
if (!value) {
|
|
146
178
|
return value
|
|
147
179
|
} else if (rxjs.isObservable(value)) {
|
|
148
|
-
return
|
|
180
|
+
return proxify(expression.observe(value), expression)
|
|
181
|
+
} else if (typeof value?.then === 'function') {
|
|
182
|
+
return proxify(expression.wait(value), expression, handler)
|
|
149
183
|
} else if (typeof value === 'object') {
|
|
150
|
-
return new Proxy(value,
|
|
184
|
+
return new Proxy(value, handler)
|
|
151
185
|
} else {
|
|
152
186
|
return value
|
|
153
187
|
}
|
|
@@ -155,7 +189,14 @@ function proxyify(value, expression) {
|
|
|
155
189
|
|
|
156
190
|
const MAP_POOL = []
|
|
157
191
|
|
|
158
|
-
|
|
192
|
+
function makeWrapper(expression) {
|
|
193
|
+
const handler = {
|
|
194
|
+
get: (target, prop) => proxify(target[prop], this),
|
|
195
|
+
}
|
|
196
|
+
return (value) => proxify(value, expression, handler)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
module.exports = ({ ds, proxify, compiler }) => {
|
|
159
200
|
class Expression {
|
|
160
201
|
constructor(context, script, expression, args, observer) {
|
|
161
202
|
this._context = context
|
|
@@ -172,19 +213,13 @@ module.exports = ({ ds, ...options }) => {
|
|
|
172
213
|
this._disposing = false
|
|
173
214
|
this._destroyed = false
|
|
174
215
|
this._subscription = null
|
|
175
|
-
this._args =
|
|
176
|
-
this.
|
|
177
|
-
this._handler = options.proxyify
|
|
178
|
-
? {
|
|
179
|
-
get: (target, prop) => proxyify(target[prop], this),
|
|
180
|
-
}
|
|
181
|
-
: null
|
|
216
|
+
this._args = kEmpty
|
|
217
|
+
this._wrap = null
|
|
182
218
|
|
|
183
219
|
if (rxjs.isObservable(args)) {
|
|
184
220
|
this._subscription = args.subscribe({
|
|
185
221
|
next: (args) => {
|
|
186
|
-
this._args =
|
|
187
|
-
this._ready = true
|
|
222
|
+
this._args = proxify ? this.wrap(args) : args
|
|
188
223
|
this._refresh()
|
|
189
224
|
},
|
|
190
225
|
error: (err) => {
|
|
@@ -196,12 +231,16 @@ module.exports = ({ ds, ...options }) => {
|
|
|
196
231
|
},
|
|
197
232
|
})
|
|
198
233
|
} else {
|
|
199
|
-
this._args =
|
|
200
|
-
this._ready = true
|
|
234
|
+
this._args = proxify ? this.wrap(args) : args
|
|
201
235
|
this._refreshNT(this)
|
|
202
236
|
}
|
|
203
237
|
}
|
|
204
238
|
|
|
239
|
+
wrap(value) {
|
|
240
|
+
this._wrap ??= makeWrapper(this)
|
|
241
|
+
return this._wrap(value)
|
|
242
|
+
}
|
|
243
|
+
|
|
205
244
|
suspend() {
|
|
206
245
|
throw kSuspend
|
|
207
246
|
}
|
|
@@ -214,6 +253,10 @@ module.exports = ({ ds, ...options }) => {
|
|
|
214
253
|
return this._getObservable(observable, throws)
|
|
215
254
|
}
|
|
216
255
|
|
|
256
|
+
wait(promise, throws) {
|
|
257
|
+
return this._getWait(promise, throws)
|
|
258
|
+
}
|
|
259
|
+
|
|
217
260
|
ds(id, state, throws) {
|
|
218
261
|
return this._getRecord(id, state, throws)
|
|
219
262
|
}
|
|
@@ -267,7 +310,7 @@ module.exports = ({ ds, ...options }) => {
|
|
|
267
310
|
_refreshNT(self) {
|
|
268
311
|
self._refreshing = false
|
|
269
312
|
|
|
270
|
-
if (self._destroyed || self._disposing ||
|
|
313
|
+
if (self._destroyed || self._disposing || self._args === kEmpty) {
|
|
271
314
|
return
|
|
272
315
|
}
|
|
273
316
|
|
|
@@ -277,6 +320,7 @@ module.exports = ({ ds, ...options }) => {
|
|
|
277
320
|
self._context.$ = self._args
|
|
278
321
|
self._context.nxt = self
|
|
279
322
|
try {
|
|
323
|
+
compiler.current = this
|
|
280
324
|
const value = self._script.runInContext(self._context)
|
|
281
325
|
if (value !== self._value) {
|
|
282
326
|
self._value = value
|
|
@@ -294,6 +338,8 @@ module.exports = ({ ds, ...options }) => {
|
|
|
294
338
|
})
|
|
295
339
|
)
|
|
296
340
|
} finally {
|
|
341
|
+
compiler.current = null
|
|
342
|
+
|
|
297
343
|
self._context.$ = null
|
|
298
344
|
self._context.nxt = null
|
|
299
345
|
|
|
@@ -321,7 +367,7 @@ module.exports = ({ ds, ...options }) => {
|
|
|
321
367
|
}
|
|
322
368
|
|
|
323
369
|
_refresh = () => {
|
|
324
|
-
if (this._refreshing || this._destroyed || this._disposing ||
|
|
370
|
+
if (this._refreshing || this._destroyed || this._disposing || this._args === kEmpty) {
|
|
325
371
|
return
|
|
326
372
|
}
|
|
327
373
|
|
|
@@ -381,6 +427,28 @@ module.exports = ({ ds, ...options }) => {
|
|
|
381
427
|
return entry.value
|
|
382
428
|
}
|
|
383
429
|
|
|
430
|
+
_getWait(promise, throws) {
|
|
431
|
+
if (typeof promise?.then !== 'function') {
|
|
432
|
+
throw new Error(`invalid argument: Promise (${promise})`)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const entry = this._getEntry(promise, PromiseEntry, promise)
|
|
436
|
+
|
|
437
|
+
if (entry.error) {
|
|
438
|
+
throw entry.error
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (entry.value === kEmpty) {
|
|
442
|
+
if (throws ?? true) {
|
|
443
|
+
throw kSuspend
|
|
444
|
+
} else {
|
|
445
|
+
return null
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return entry.value
|
|
450
|
+
}
|
|
451
|
+
|
|
384
452
|
_getRecord(key, state, throws) {
|
|
385
453
|
if (!key || typeof key !== 'string') {
|
|
386
454
|
throw new Error(`invalid argument: key (${key})`)
|