@nordcraft/runtime 1.0.68 → 1.0.70
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/dist/api/createAPIv2.js +12 -6
- package/dist/api/createAPIv2.js.map +1 -1
- package/dist/components/createElement.js +48 -34
- package/dist/components/createElement.js.map +1 -1
- package/dist/custom-element.main.esm.js +16 -16
- package/dist/custom-element.main.esm.js.map +3 -3
- package/dist/page.main.esm.js +3 -3
- package/dist/page.main.esm.js.map +3 -3
- package/dist/signal/signal.d.ts +1 -0
- package/dist/signal/signal.js +20 -8
- package/dist/signal/signal.js.map +1 -1
- package/package.json +3 -3
- package/src/api/createAPIv2.ts +13 -6
- package/src/components/createElement.ts +72 -41
- package/src/signal/signal.ts +21 -8
package/dist/signal/signal.d.ts
CHANGED
package/dist/signal/signal.js
CHANGED
|
@@ -3,6 +3,7 @@ export class Signal {
|
|
|
3
3
|
value;
|
|
4
4
|
subscribers;
|
|
5
5
|
subscriptions;
|
|
6
|
+
destroying = false;
|
|
6
7
|
constructor(value) {
|
|
7
8
|
this.value = value;
|
|
8
9
|
this.subscribers = new Set();
|
|
@@ -19,7 +20,9 @@ export class Signal {
|
|
|
19
20
|
}
|
|
20
21
|
if (fastDeepEqual(value, this.value) === false) {
|
|
21
22
|
this.value = value;
|
|
22
|
-
|
|
23
|
+
for (const subscriber of this.subscribers) {
|
|
24
|
+
subscriber.notify(this.value);
|
|
25
|
+
}
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
update(f) {
|
|
@@ -34,16 +37,25 @@ export class Signal {
|
|
|
34
37
|
};
|
|
35
38
|
}
|
|
36
39
|
destroy() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
// Prevent re-entrancy
|
|
41
|
+
if (this.destroying) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.destroying = true;
|
|
45
|
+
for (const subscriber of this.subscribers) {
|
|
46
|
+
subscriber.destroy?.();
|
|
47
|
+
}
|
|
40
48
|
this.subscribers.clear();
|
|
41
|
-
this.subscriptions
|
|
49
|
+
for (const subscription of this.subscriptions) {
|
|
50
|
+
subscription();
|
|
51
|
+
}
|
|
52
|
+
this.subscriptions.splice(0, this.subscriptions.length);
|
|
53
|
+
this.destroying = false;
|
|
42
54
|
}
|
|
43
55
|
cleanSubscribers() {
|
|
44
|
-
this.subscribers
|
|
45
|
-
destroy?.();
|
|
46
|
-
}
|
|
56
|
+
for (const subscriber of this.subscribers) {
|
|
57
|
+
subscriber.destroy?.();
|
|
58
|
+
}
|
|
47
59
|
this.subscribers.clear();
|
|
48
60
|
}
|
|
49
61
|
map(f) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../src/signal/signal.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,iBAAiB,CAAA;AAE3C,MAAM,OAAO,MAAM;IACjB,KAAK,CAAG;IACR,WAAW,CAGT;IACF,aAAa,CAAmB;
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../src/signal/signal.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://github.com/nordcraftengine/nordcraft",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@nordcraft/core": "1.0.
|
|
8
|
-
"@nordcraft/std-lib": "1.0.
|
|
7
|
+
"@nordcraft/core": "1.0.70",
|
|
8
|
+
"@nordcraft/std-lib": "1.0.70",
|
|
9
9
|
"fast-deep-equal": "3.1.3",
|
|
10
10
|
"path-to-regexp": "6.3.0"
|
|
11
11
|
},
|
|
@@ -21,5 +21,5 @@
|
|
|
21
21
|
"files": ["dist", "src"],
|
|
22
22
|
"main": "dist/page.main.js",
|
|
23
23
|
"types": "dist/page.main.d.ts",
|
|
24
|
-
"version": "1.0.
|
|
24
|
+
"version": "1.0.70"
|
|
25
25
|
}
|
package/src/api/createAPIv2.ts
CHANGED
|
@@ -957,6 +957,7 @@ export function createAPI({
|
|
|
957
957
|
| Signal<{
|
|
958
958
|
request: ReturnType<typeof constructRequest>
|
|
959
959
|
api: ReturnType<typeof getApiForComparison>
|
|
960
|
+
headers: Array<[string, string]>
|
|
960
961
|
// if the evaluated value of autoFetch changes from false -> true, we need to refetch the api
|
|
961
962
|
autoFetch: boolean
|
|
962
963
|
// currently, the proxy setting is always controlled by a "value formula", but in case we later
|
|
@@ -966,19 +967,22 @@ export function createAPI({
|
|
|
966
967
|
| undefined
|
|
967
968
|
|
|
968
969
|
// eslint-disable-next-line prefer-const
|
|
969
|
-
payloadSignal = ctx.dataSignal.map((
|
|
970
|
-
const payloadContext = getFormulaContext(api,
|
|
970
|
+
payloadSignal = ctx.dataSignal.map((data) => {
|
|
971
|
+
const payloadContext = getFormulaContext(api, data)
|
|
972
|
+
const request = constructRequest(api, data)
|
|
971
973
|
return {
|
|
972
|
-
request
|
|
974
|
+
request,
|
|
973
975
|
api: getApiForComparison(api),
|
|
976
|
+
// Serialize the Headers object to be able to compare changes
|
|
977
|
+
headers: Array.from(request.requestSettings.headers.entries()),
|
|
974
978
|
autoFetch: api.autoFetch
|
|
975
979
|
? applyFormula(api.autoFetch, payloadContext)
|
|
976
980
|
: false,
|
|
977
981
|
proxy: applyFormula(api.server?.proxy?.enabled.formula, payloadContext),
|
|
978
982
|
}
|
|
979
983
|
})
|
|
980
|
-
payloadSignal.subscribe(async (
|
|
981
|
-
const { url, requestSettings } =
|
|
984
|
+
payloadSignal.subscribe(async (apiData) => {
|
|
985
|
+
const { url, requestSettings } = apiData.request
|
|
982
986
|
// Ensure we only use caching if the page is currently loading
|
|
983
987
|
const cacheMatch =
|
|
984
988
|
// We lookup the API from cache as long as autofetch is defined (and not statically falsy)
|
|
@@ -1138,14 +1142,17 @@ export function createAPI({
|
|
|
1138
1142
|
const autoFetch =
|
|
1139
1143
|
api.autoFetch && applyFormula(api.autoFetch, updateContext)
|
|
1140
1144
|
if (autoFetch) {
|
|
1145
|
+
const request = constructRequest(newApi, componentData)
|
|
1141
1146
|
payloadSignal?.set({
|
|
1142
|
-
request
|
|
1147
|
+
request,
|
|
1143
1148
|
api: getApiForComparison(newApi),
|
|
1144
1149
|
autoFetch,
|
|
1145
1150
|
proxy: applyFormula(
|
|
1146
1151
|
newApi.server?.proxy?.enabled.formula,
|
|
1147
1152
|
updateContext,
|
|
1148
1153
|
),
|
|
1154
|
+
// Serialize the Headers object to be able to compare changes
|
|
1155
|
+
headers: Array.from(request.requestSettings.headers.entries()),
|
|
1149
1156
|
})
|
|
1150
1157
|
}
|
|
1151
1158
|
},
|
|
@@ -11,8 +11,10 @@ import {
|
|
|
11
11
|
import { appendUnit } from '@nordcraft/core/dist/styling/customProperty'
|
|
12
12
|
import { getNodeSelector } from '@nordcraft/core/dist/utils/getNodeSelector'
|
|
13
13
|
import { isDefined, toBoolean } from '@nordcraft/core/dist/utils/util'
|
|
14
|
+
import type { ComponentData } from '@nordcraft/core/src/component/component.types'
|
|
14
15
|
import { handleAction } from '../events/handleAction'
|
|
15
16
|
import type { Signal } from '../signal/signal'
|
|
17
|
+
import type { ComponentContext } from '../types'
|
|
16
18
|
import { getDragData } from '../utils/getDragData'
|
|
17
19
|
import { getElementTagName } from '../utils/getElementTagName'
|
|
18
20
|
import { setAttribute } from '../utils/setAttribute'
|
|
@@ -210,39 +212,20 @@ export function createElement({
|
|
|
210
212
|
)
|
|
211
213
|
})
|
|
212
214
|
|
|
213
|
-
|
|
215
|
+
const eventHandlers: [string, (e: Event) => boolean][] = []
|
|
214
216
|
Object.values(node.events).forEach((event) => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (e instanceof DragEvent) {
|
|
218
|
-
;(e as any).data = getDragData(e)
|
|
219
|
-
}
|
|
220
|
-
if (e instanceof ClipboardEvent) {
|
|
221
|
-
try {
|
|
222
|
-
;(e as any).data = Array.from(e.clipboardData?.items ?? []).reduce<
|
|
223
|
-
Record<string, any>
|
|
224
|
-
>((dragData, item) => {
|
|
225
|
-
try {
|
|
226
|
-
dragData[item.type] = JSON.parse(
|
|
227
|
-
e.clipboardData?.getData(item.type) as any,
|
|
228
|
-
)
|
|
229
|
-
} catch {
|
|
230
|
-
dragData[item.type] = e.clipboardData?.getData(item.type)
|
|
231
|
-
}
|
|
232
|
-
return dragData
|
|
233
|
-
}, {})
|
|
234
|
-
} catch (e) {
|
|
235
|
-
// eslint-disable-next-line no-console
|
|
236
|
-
console.error('Could not get paste data', e)
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
void handleAction(action, { ...dataSignal.get(), Event: e }, ctx, e)
|
|
240
|
-
})
|
|
241
|
-
return false
|
|
242
|
-
}
|
|
243
|
-
if (event) {
|
|
244
|
-
elem.addEventListener(event.trigger, handler)
|
|
217
|
+
if (!event) {
|
|
218
|
+
return
|
|
245
219
|
}
|
|
220
|
+
|
|
221
|
+
eventHandlers.push([
|
|
222
|
+
event.trigger,
|
|
223
|
+
getEventHandler({ event, dataSignal, ctx }),
|
|
224
|
+
])
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
eventHandlers.forEach(([eventName, handler]) => {
|
|
228
|
+
elem.addEventListener(eventName, handler)
|
|
246
229
|
})
|
|
247
230
|
|
|
248
231
|
// for script, style & SVG<text> tags we only render text child.
|
|
@@ -290,19 +273,67 @@ export function createElement({
|
|
|
290
273
|
})
|
|
291
274
|
})
|
|
292
275
|
} else {
|
|
276
|
+
const childNodes: (Element | Text)[] = []
|
|
293
277
|
node.children.forEach((child, i) => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
278
|
+
childNodes.push(
|
|
279
|
+
...createNode({
|
|
280
|
+
parentElement: elem,
|
|
281
|
+
id: child,
|
|
282
|
+
path: path + '.' + i,
|
|
283
|
+
dataSignal,
|
|
284
|
+
ctx,
|
|
285
|
+
namespace,
|
|
286
|
+
instance,
|
|
287
|
+
}),
|
|
288
|
+
)
|
|
304
289
|
})
|
|
290
|
+
elem.append(...childNodes)
|
|
305
291
|
}
|
|
292
|
+
dataSignal.subscribe(() => {}, {
|
|
293
|
+
destroy: () => {
|
|
294
|
+
// TODO: Clean up event listeners, but after destruction of child signals (Maybe we need a "afterDestroy" hook on signals?)
|
|
295
|
+
elem.parentNode?.removeChild(elem)
|
|
296
|
+
},
|
|
297
|
+
})
|
|
306
298
|
|
|
307
299
|
return elem
|
|
308
300
|
}
|
|
301
|
+
|
|
302
|
+
const getEventHandler =
|
|
303
|
+
({
|
|
304
|
+
event,
|
|
305
|
+
dataSignal,
|
|
306
|
+
ctx,
|
|
307
|
+
}: {
|
|
308
|
+
event: ElementNodeModel['events'][string]
|
|
309
|
+
dataSignal: Signal<ComponentData>
|
|
310
|
+
ctx: ComponentContext
|
|
311
|
+
}) =>
|
|
312
|
+
(e: Event) => {
|
|
313
|
+
event?.actions.forEach((action) => {
|
|
314
|
+
if (e instanceof DragEvent) {
|
|
315
|
+
;(e as any).data = getDragData(e)
|
|
316
|
+
}
|
|
317
|
+
if (e instanceof ClipboardEvent) {
|
|
318
|
+
try {
|
|
319
|
+
;(e as any).data = Array.from(e.clipboardData?.items ?? []).reduce<
|
|
320
|
+
Record<string, any>
|
|
321
|
+
>((dragData, item) => {
|
|
322
|
+
try {
|
|
323
|
+
dragData[item.type] = JSON.parse(
|
|
324
|
+
e.clipboardData?.getData(item.type) as any,
|
|
325
|
+
)
|
|
326
|
+
} catch {
|
|
327
|
+
dragData[item.type] = e.clipboardData?.getData(item.type)
|
|
328
|
+
}
|
|
329
|
+
return dragData
|
|
330
|
+
}, {})
|
|
331
|
+
} catch (e) {
|
|
332
|
+
// eslint-disable-next-line no-console
|
|
333
|
+
console.error('Could not get paste data', e)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
void handleAction(action, { ...dataSignal.get(), Event: e }, ctx, e)
|
|
337
|
+
})
|
|
338
|
+
return false
|
|
339
|
+
}
|
package/src/signal/signal.ts
CHANGED
|
@@ -7,6 +7,7 @@ export class Signal<T> {
|
|
|
7
7
|
destroy?: () => void
|
|
8
8
|
}>
|
|
9
9
|
subscriptions: Array<() => void>
|
|
10
|
+
destroying = false
|
|
10
11
|
|
|
11
12
|
constructor(value: T) {
|
|
12
13
|
this.value = value
|
|
@@ -25,7 +26,9 @@ export class Signal<T> {
|
|
|
25
26
|
|
|
26
27
|
if (fastDeepEqual(value, this.value) === false) {
|
|
27
28
|
this.value = value
|
|
28
|
-
|
|
29
|
+
for (const subscriber of this.subscribers) {
|
|
30
|
+
subscriber.notify(this.value)
|
|
31
|
+
}
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
|
|
@@ -41,16 +44,26 @@ export class Signal<T> {
|
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
destroy() {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
// Prevent re-entrancy
|
|
48
|
+
if (this.destroying) {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.destroying = true
|
|
53
|
+
for (const subscriber of this.subscribers) {
|
|
54
|
+
subscriber.destroy?.()
|
|
55
|
+
}
|
|
47
56
|
this.subscribers.clear()
|
|
48
|
-
this.subscriptions
|
|
57
|
+
for (const subscription of this.subscriptions) {
|
|
58
|
+
subscription()
|
|
59
|
+
}
|
|
60
|
+
this.subscriptions.splice(0, this.subscriptions.length)
|
|
61
|
+
this.destroying = false
|
|
49
62
|
}
|
|
50
63
|
cleanSubscribers() {
|
|
51
|
-
this.subscribers
|
|
52
|
-
destroy?.()
|
|
53
|
-
}
|
|
64
|
+
for (const subscriber of this.subscribers) {
|
|
65
|
+
subscriber.destroy?.()
|
|
66
|
+
}
|
|
54
67
|
this.subscribers.clear()
|
|
55
68
|
}
|
|
56
69
|
map<T2>(f: (value: T) => T2): Signal<T2> {
|