@nordcraft/runtime 1.0.13 → 1.0.15
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/apiUtils.d.ts +2 -0
- package/dist/api/apiUtils.js +2 -0
- package/dist/api/apiUtils.js.map +1 -0
- package/dist/api/createAPI.d.ts +2 -2
- package/dist/api/createAPIv2.d.ts +7 -3
- package/dist/api/createAPIv2.js +143 -82
- package/dist/api/createAPIv2.js.map +1 -1
- package/dist/components/createComponent.js +21 -16
- package/dist/components/createComponent.js.map +1 -1
- package/dist/components/renderComponent.d.ts +2 -5
- package/dist/components/renderComponent.js.map +1 -1
- package/dist/custom-element/ToddleComponent.js +8 -3
- package/dist/custom-element/ToddleComponent.js.map +1 -1
- package/dist/custom-element.main.esm.js +44 -44
- package/dist/custom-element.main.esm.js.map +4 -4
- package/dist/editor-preview.main.js +10 -5
- package/dist/editor-preview.main.js.map +1 -1
- package/dist/events/handleAction.js +29 -29
- package/dist/events/handleAction.js.map +1 -1
- package/dist/page.main.esm.js +3 -3
- package/dist/page.main.esm.js.map +4 -4
- package/dist/page.main.js +8 -3
- package/dist/page.main.js.map +1 -1
- package/package.json +3 -3
- package/src/api/apiUtils.ts +4 -0
- package/src/api/createAPI.ts +1 -1
- package/src/api/createAPIv2.ts +267 -141
- package/src/components/createComponent.ts +24 -23
- package/src/components/renderComponent.ts +2 -1
- package/src/custom-element/ToddleComponent.ts +10 -8
- package/src/editor-preview.main.ts +11 -5
- package/src/events/handleAction.ts +42 -46
- package/src/page.main.ts +9 -8
- package/src/types.d.ts +34 -5
package/src/api/createAPIv2.ts
CHANGED
|
@@ -18,14 +18,13 @@ import {
|
|
|
18
18
|
isJsonStreamHeader,
|
|
19
19
|
isTextHeader,
|
|
20
20
|
} from '@nordcraft/core/dist/api/headers'
|
|
21
|
-
import type {
|
|
21
|
+
import type { ComponentData } from '@nordcraft/core/dist/component/component.types'
|
|
22
22
|
import type {
|
|
23
23
|
Formula,
|
|
24
24
|
FormulaContext,
|
|
25
|
-
ValueOperationValue,
|
|
26
25
|
} from '@nordcraft/core/dist/formula/formula'
|
|
27
26
|
import { applyFormula } from '@nordcraft/core/dist/formula/formula'
|
|
28
|
-
import type { NestedOmit
|
|
27
|
+
import type { NestedOmit } from '@nordcraft/core/dist/types'
|
|
29
28
|
import {
|
|
30
29
|
omitPaths,
|
|
31
30
|
sortObjectEntries,
|
|
@@ -34,20 +33,28 @@ import { PROXY_URL_HEADER, validateUrl } from '@nordcraft/core/dist/utils/url'
|
|
|
34
33
|
import { isDefined } from '@nordcraft/core/dist/utils/util'
|
|
35
34
|
import { handleAction } from '../events/handleAction'
|
|
36
35
|
import type { Signal } from '../signal/signal'
|
|
37
|
-
import type { ComponentContext,
|
|
36
|
+
import type { ComponentContext, ContextApiV2 } from '../types'
|
|
38
37
|
|
|
39
38
|
/**
|
|
40
39
|
* Set up an api v2 for a component.
|
|
41
40
|
*/
|
|
42
|
-
export function createAPI(
|
|
43
|
-
apiRequest
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
export function createAPI({
|
|
42
|
+
apiRequest,
|
|
43
|
+
componentData: initialComponentData,
|
|
44
|
+
ctx,
|
|
45
|
+
}: {
|
|
46
|
+
apiRequest: ApiRequest
|
|
47
|
+
componentData: ComponentData
|
|
48
|
+
ctx: ComponentContext
|
|
49
|
+
}): ContextApiV2 {
|
|
46
50
|
// If `__toddle` isn't found it is in a web component context. We behave as if the page isn't loaded.
|
|
47
51
|
let timer: any = null
|
|
48
52
|
let api = { ...apiRequest }
|
|
49
53
|
|
|
50
|
-
function constructRequest(
|
|
54
|
+
function constructRequest(
|
|
55
|
+
api: ApiRequest,
|
|
56
|
+
componentData: ComponentData,
|
|
57
|
+
): ReturnType<typeof createApiRequest> {
|
|
51
58
|
// Get baseUrl and validate it. (It wont be in web component context)
|
|
52
59
|
let baseUrl: string | undefined = window.origin
|
|
53
60
|
try {
|
|
@@ -56,16 +63,33 @@ export function createAPI(
|
|
|
56
63
|
baseUrl = undefined
|
|
57
64
|
}
|
|
58
65
|
|
|
59
|
-
|
|
66
|
+
const request = createApiRequest({
|
|
60
67
|
api,
|
|
61
|
-
formulaContext: getFormulaContext(api),
|
|
68
|
+
formulaContext: getFormulaContext(api, componentData),
|
|
62
69
|
baseUrl,
|
|
63
70
|
defaultHeaders: undefined,
|
|
64
71
|
})
|
|
72
|
+
return {
|
|
73
|
+
...request,
|
|
74
|
+
requestSettings: {
|
|
75
|
+
...request.requestSettings,
|
|
76
|
+
// credentials is a browser specific setting and cannot be set in the
|
|
77
|
+
// createApiRequest function directly as it's shared between server and client
|
|
78
|
+
credentials:
|
|
79
|
+
api.client?.credentials &&
|
|
80
|
+
['include', 'same-origin', 'omit'].includes(api.client.credentials)
|
|
81
|
+
? api.client.credentials
|
|
82
|
+
: // Default to same-origin
|
|
83
|
+
undefined,
|
|
84
|
+
},
|
|
85
|
+
}
|
|
65
86
|
}
|
|
66
87
|
|
|
67
88
|
// Create the formula context for the api
|
|
68
|
-
function getFormulaContext(
|
|
89
|
+
function getFormulaContext(
|
|
90
|
+
api: ApiRequest,
|
|
91
|
+
componentData: ComponentData | undefined,
|
|
92
|
+
): FormulaContext {
|
|
69
93
|
// Use the general formula context to evaluate the arguments of the api
|
|
70
94
|
const formulaContext = {
|
|
71
95
|
data: ctx.dataSignal.get(),
|
|
@@ -87,6 +111,7 @@ export function createAPI(
|
|
|
87
111
|
|
|
88
112
|
const data = {
|
|
89
113
|
...formulaContext.data,
|
|
114
|
+
...componentData,
|
|
90
115
|
ApiInputs: {
|
|
91
116
|
...evaluatedInputs,
|
|
92
117
|
},
|
|
@@ -103,15 +128,16 @@ export function createAPI(
|
|
|
103
128
|
}
|
|
104
129
|
}
|
|
105
130
|
|
|
106
|
-
function handleRedirectRules(api: ApiRequest) {
|
|
131
|
+
function handleRedirectRules(api: ApiRequest, componentData: ComponentData) {
|
|
107
132
|
for (const [ruleName, rule] of sortObjectEntries(
|
|
108
133
|
api.redirectRules ?? {},
|
|
109
134
|
([_, rule]) => rule.index,
|
|
110
135
|
)) {
|
|
136
|
+
const formulaContext = getFormulaContext(api, componentData)
|
|
111
137
|
const location = applyFormula(rule.formula, {
|
|
112
|
-
...
|
|
138
|
+
...formulaContext,
|
|
113
139
|
data: {
|
|
114
|
-
...
|
|
140
|
+
...formulaContext.data,
|
|
115
141
|
Apis: {
|
|
116
142
|
[api.name]: ctx.dataSignal.get().Apis?.[api.name] as ApiStatus,
|
|
117
143
|
},
|
|
@@ -138,15 +164,22 @@ export function createAPI(
|
|
|
138
164
|
}
|
|
139
165
|
}
|
|
140
166
|
|
|
141
|
-
function triggerActions(
|
|
142
|
-
eventName
|
|
143
|
-
api
|
|
167
|
+
function triggerActions({
|
|
168
|
+
eventName,
|
|
169
|
+
api,
|
|
170
|
+
data,
|
|
171
|
+
componentData,
|
|
172
|
+
}: {
|
|
173
|
+
eventName: 'message' | 'success' | 'failed'
|
|
174
|
+
api: ApiRequest
|
|
144
175
|
data: {
|
|
145
176
|
body: unknown
|
|
146
177
|
status?: number
|
|
147
178
|
headers?: Record<string, string>
|
|
148
|
-
}
|
|
149
|
-
|
|
179
|
+
}
|
|
180
|
+
componentData: ComponentData
|
|
181
|
+
}) {
|
|
182
|
+
const formulaContext = getFormulaContext(api, componentData)
|
|
150
183
|
switch (eventName) {
|
|
151
184
|
case 'message': {
|
|
152
185
|
const event = createApiEvent('message', data.body)
|
|
@@ -154,8 +187,7 @@ export function createAPI(
|
|
|
154
187
|
handleAction(
|
|
155
188
|
action,
|
|
156
189
|
{
|
|
157
|
-
...
|
|
158
|
-
...ctx.dataSignal.get(),
|
|
190
|
+
...formulaContext.data,
|
|
159
191
|
Event: event,
|
|
160
192
|
},
|
|
161
193
|
ctx,
|
|
@@ -170,8 +202,7 @@ export function createAPI(
|
|
|
170
202
|
handleAction(
|
|
171
203
|
action,
|
|
172
204
|
{
|
|
173
|
-
...
|
|
174
|
-
...ctx.dataSignal.get(),
|
|
205
|
+
...formulaContext.data,
|
|
175
206
|
Event: event,
|
|
176
207
|
},
|
|
177
208
|
ctx,
|
|
@@ -189,8 +220,7 @@ export function createAPI(
|
|
|
189
220
|
handleAction(
|
|
190
221
|
action,
|
|
191
222
|
{
|
|
192
|
-
...
|
|
193
|
-
...ctx.dataSignal.get(),
|
|
223
|
+
...formulaContext.data,
|
|
194
224
|
Event: event,
|
|
195
225
|
},
|
|
196
226
|
ctx,
|
|
@@ -202,15 +232,21 @@ export function createAPI(
|
|
|
202
232
|
}
|
|
203
233
|
}
|
|
204
234
|
|
|
205
|
-
function apiSuccess(
|
|
206
|
-
api
|
|
235
|
+
function apiSuccess({
|
|
236
|
+
api,
|
|
237
|
+
componentData,
|
|
238
|
+
data,
|
|
239
|
+
performance,
|
|
240
|
+
}: {
|
|
241
|
+
api: ApiRequest
|
|
242
|
+
componentData: ComponentData
|
|
207
243
|
data: {
|
|
208
244
|
body: unknown
|
|
209
245
|
status?: number
|
|
210
246
|
headers?: Record<string, string>
|
|
211
|
-
}
|
|
212
|
-
performance: ApiPerformance
|
|
213
|
-
) {
|
|
247
|
+
}
|
|
248
|
+
performance: ApiPerformance
|
|
249
|
+
}) {
|
|
214
250
|
const latestRequestStart =
|
|
215
251
|
ctx.dataSignal.get().Apis?.[api.name]?.response?.performance?.requestStart
|
|
216
252
|
if (
|
|
@@ -236,7 +272,7 @@ export function createAPI(
|
|
|
236
272
|
},
|
|
237
273
|
},
|
|
238
274
|
})
|
|
239
|
-
const appliedRedirectRule = handleRedirectRules(api)
|
|
275
|
+
const appliedRedirectRule = handleRedirectRules(api, componentData)
|
|
240
276
|
if (appliedRedirectRule) {
|
|
241
277
|
ctx.dataSignal.set({
|
|
242
278
|
...ctx.dataSignal.get(),
|
|
@@ -260,15 +296,21 @@ export function createAPI(
|
|
|
260
296
|
}
|
|
261
297
|
}
|
|
262
298
|
|
|
263
|
-
function apiError(
|
|
264
|
-
api
|
|
299
|
+
function apiError({
|
|
300
|
+
api,
|
|
301
|
+
componentData,
|
|
302
|
+
data,
|
|
303
|
+
performance,
|
|
304
|
+
}: {
|
|
305
|
+
api: ApiRequest
|
|
306
|
+
componentData: ComponentData
|
|
265
307
|
data: {
|
|
266
308
|
body: unknown
|
|
267
309
|
status?: number
|
|
268
310
|
headers?: Record<string, string>
|
|
269
|
-
}
|
|
270
|
-
performance: ApiPerformance
|
|
271
|
-
) {
|
|
311
|
+
}
|
|
312
|
+
performance: ApiPerformance
|
|
313
|
+
}) {
|
|
272
314
|
const latestRequestStart =
|
|
273
315
|
ctx.dataSignal.get().Apis?.[api.name]?.response?.performance?.requestStart
|
|
274
316
|
if (
|
|
@@ -293,7 +335,7 @@ export function createAPI(
|
|
|
293
335
|
},
|
|
294
336
|
},
|
|
295
337
|
})
|
|
296
|
-
const appliedRedirectRule = handleRedirectRules(api)
|
|
338
|
+
const appliedRedirectRule = handleRedirectRules(api, componentData)
|
|
297
339
|
if (appliedRedirectRule) {
|
|
298
340
|
ctx.dataSignal.set({
|
|
299
341
|
...ctx.dataSignal.get(),
|
|
@@ -318,11 +360,17 @@ export function createAPI(
|
|
|
318
360
|
}
|
|
319
361
|
|
|
320
362
|
// Execute the request - potentially to the cloudflare Query proxy
|
|
321
|
-
async function execute(
|
|
322
|
-
api
|
|
323
|
-
url
|
|
324
|
-
requestSettings
|
|
325
|
-
|
|
363
|
+
async function execute({
|
|
364
|
+
api,
|
|
365
|
+
url,
|
|
366
|
+
requestSettings,
|
|
367
|
+
componentData,
|
|
368
|
+
}: {
|
|
369
|
+
api: ApiRequest
|
|
370
|
+
url: URL
|
|
371
|
+
requestSettings: ToddleRequestInit
|
|
372
|
+
componentData: ComponentData
|
|
373
|
+
}) {
|
|
326
374
|
const run = async () => {
|
|
327
375
|
const performance: ApiPerformance = {
|
|
328
376
|
requestStart: Date.now(),
|
|
@@ -346,7 +394,7 @@ export function createAPI(
|
|
|
346
394
|
const proxy = api.server?.proxy
|
|
347
395
|
? (applyFormula(
|
|
348
396
|
api.server.proxy.enabled.formula,
|
|
349
|
-
getFormulaContext(api),
|
|
397
|
+
getFormulaContext(api, componentData),
|
|
350
398
|
) ?? false)
|
|
351
399
|
: false
|
|
352
400
|
|
|
@@ -368,14 +416,24 @@ export function createAPI(
|
|
|
368
416
|
}
|
|
369
417
|
|
|
370
418
|
performance.responseStart = Date.now()
|
|
371
|
-
await handleResponse(api, response, performance)
|
|
419
|
+
await handleResponse({ api, componentData, res: response, performance })
|
|
372
420
|
return
|
|
373
421
|
} catch (error: any) {
|
|
374
422
|
const body = error.cause
|
|
375
423
|
? { message: error.message, data: error.cause }
|
|
376
424
|
: error.message
|
|
377
|
-
apiError(
|
|
378
|
-
|
|
425
|
+
apiError({
|
|
426
|
+
api,
|
|
427
|
+
componentData,
|
|
428
|
+
data: { body },
|
|
429
|
+
performance: { ...performance, responseEnd: Date.now() },
|
|
430
|
+
})
|
|
431
|
+
triggerActions({
|
|
432
|
+
eventName: 'failed',
|
|
433
|
+
api,
|
|
434
|
+
data: { body },
|
|
435
|
+
componentData,
|
|
436
|
+
})
|
|
379
437
|
return Promise.reject(error)
|
|
380
438
|
}
|
|
381
439
|
}
|
|
@@ -390,7 +448,10 @@ export function createAPI(
|
|
|
390
448
|
() => {
|
|
391
449
|
run().then(resolve, reject)
|
|
392
450
|
},
|
|
393
|
-
applyFormula(
|
|
451
|
+
applyFormula(
|
|
452
|
+
api.client?.debounce?.formula,
|
|
453
|
+
getFormulaContext(api, componentData),
|
|
454
|
+
),
|
|
394
455
|
)
|
|
395
456
|
})
|
|
396
457
|
}
|
|
@@ -398,11 +459,17 @@ export function createAPI(
|
|
|
398
459
|
return run()
|
|
399
460
|
}
|
|
400
461
|
|
|
401
|
-
function handleResponse(
|
|
402
|
-
api
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
462
|
+
function handleResponse({
|
|
463
|
+
api,
|
|
464
|
+
componentData,
|
|
465
|
+
res,
|
|
466
|
+
performance,
|
|
467
|
+
}: {
|
|
468
|
+
api: ApiRequest
|
|
469
|
+
componentData: ComponentData
|
|
470
|
+
res: Response
|
|
471
|
+
performance: ApiPerformance
|
|
472
|
+
}) {
|
|
406
473
|
let parserMode = api.client?.parserMode ?? 'auto'
|
|
407
474
|
|
|
408
475
|
if (parserMode === 'auto') {
|
|
@@ -424,25 +491,31 @@ export function createAPI(
|
|
|
424
491
|
|
|
425
492
|
switch (parserMode) {
|
|
426
493
|
case 'text':
|
|
427
|
-
return textStreamResponse(api, res, performance)
|
|
494
|
+
return textStreamResponse({ api, componentData, res, performance })
|
|
428
495
|
case 'json':
|
|
429
|
-
return jsonResponse(api, res, performance)
|
|
496
|
+
return jsonResponse({ api, componentData, res, performance })
|
|
430
497
|
case 'event-stream':
|
|
431
|
-
return eventStreamingResponse(api, res, performance)
|
|
498
|
+
return eventStreamingResponse({ api, componentData, res, performance })
|
|
432
499
|
case 'json-stream':
|
|
433
|
-
return jsonStreamResponse(api, res, performance)
|
|
500
|
+
return jsonStreamResponse({ api, componentData, res, performance })
|
|
434
501
|
case 'blob':
|
|
435
|
-
return blobResponse(api, res, performance)
|
|
502
|
+
return blobResponse({ api, componentData, res, performance })
|
|
436
503
|
default:
|
|
437
|
-
return textStreamResponse(api, res, performance)
|
|
504
|
+
return textStreamResponse({ api, componentData, res, performance })
|
|
438
505
|
}
|
|
439
506
|
}
|
|
440
507
|
|
|
441
|
-
function textStreamResponse(
|
|
442
|
-
api
|
|
443
|
-
res
|
|
444
|
-
performance
|
|
445
|
-
|
|
508
|
+
function textStreamResponse({
|
|
509
|
+
api,
|
|
510
|
+
res,
|
|
511
|
+
performance,
|
|
512
|
+
componentData,
|
|
513
|
+
}: {
|
|
514
|
+
api: ApiRequest
|
|
515
|
+
res: Response
|
|
516
|
+
performance: ApiPerformance
|
|
517
|
+
componentData: ComponentData
|
|
518
|
+
}) {
|
|
446
519
|
return handleStreaming({
|
|
447
520
|
api,
|
|
448
521
|
res,
|
|
@@ -451,14 +524,21 @@ export function createAPI(
|
|
|
451
524
|
useTextDecoder: true,
|
|
452
525
|
parseChunk: (chunk) => chunk,
|
|
453
526
|
parseChunksForData: (chunks) => chunks.join(''),
|
|
527
|
+
componentData,
|
|
454
528
|
})
|
|
455
529
|
}
|
|
456
530
|
|
|
457
|
-
function jsonStreamResponse(
|
|
458
|
-
api
|
|
459
|
-
res
|
|
460
|
-
performance
|
|
461
|
-
|
|
531
|
+
function jsonStreamResponse({
|
|
532
|
+
api,
|
|
533
|
+
res,
|
|
534
|
+
performance,
|
|
535
|
+
componentData,
|
|
536
|
+
}: {
|
|
537
|
+
api: ApiRequest
|
|
538
|
+
res: Response
|
|
539
|
+
performance: ApiPerformance
|
|
540
|
+
componentData: ComponentData
|
|
541
|
+
}) {
|
|
462
542
|
const parseChunk = (chunk: any) => {
|
|
463
543
|
let parsedData = chunk
|
|
464
544
|
try {
|
|
@@ -480,14 +560,21 @@ export function createAPI(
|
|
|
480
560
|
parseChunk,
|
|
481
561
|
parseChunksForData: (chunks) => [...chunks],
|
|
482
562
|
delimiters: ['\r\n', '\n'],
|
|
563
|
+
componentData,
|
|
483
564
|
})
|
|
484
565
|
}
|
|
485
566
|
|
|
486
|
-
async function jsonResponse(
|
|
487
|
-
api
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
567
|
+
async function jsonResponse({
|
|
568
|
+
api,
|
|
569
|
+
componentData,
|
|
570
|
+
res,
|
|
571
|
+
performance,
|
|
572
|
+
}: {
|
|
573
|
+
api: ApiRequest
|
|
574
|
+
componentData: ComponentData
|
|
575
|
+
res: Response
|
|
576
|
+
performance: ApiPerformance
|
|
577
|
+
}) {
|
|
491
578
|
const body = await res.json()
|
|
492
579
|
|
|
493
580
|
const status: ApiStatus = {
|
|
@@ -499,14 +586,20 @@ export function createAPI(
|
|
|
499
586
|
headers: Object.fromEntries(res.headers.entries()),
|
|
500
587
|
},
|
|
501
588
|
}
|
|
502
|
-
return endResponse(api, status, performance)
|
|
589
|
+
return endResponse({ api, apiStatus: status, componentData, performance })
|
|
503
590
|
}
|
|
504
591
|
|
|
505
|
-
async function blobResponse(
|
|
506
|
-
api
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
592
|
+
async function blobResponse({
|
|
593
|
+
api,
|
|
594
|
+
componentData,
|
|
595
|
+
res,
|
|
596
|
+
performance,
|
|
597
|
+
}: {
|
|
598
|
+
api: ApiRequest
|
|
599
|
+
componentData: ComponentData
|
|
600
|
+
res: Response
|
|
601
|
+
performance: ApiPerformance
|
|
602
|
+
}) {
|
|
510
603
|
const blob = await res.blob()
|
|
511
604
|
|
|
512
605
|
const status: ApiStatus = {
|
|
@@ -518,14 +611,20 @@ export function createAPI(
|
|
|
518
611
|
headers: Object.fromEntries(res.headers.entries()),
|
|
519
612
|
},
|
|
520
613
|
}
|
|
521
|
-
return endResponse(api, status, performance)
|
|
614
|
+
return endResponse({ api, apiStatus: status, componentData, performance })
|
|
522
615
|
}
|
|
523
616
|
|
|
524
|
-
function eventStreamingResponse(
|
|
525
|
-
api
|
|
526
|
-
res
|
|
527
|
-
performance
|
|
528
|
-
|
|
617
|
+
function eventStreamingResponse({
|
|
618
|
+
api,
|
|
619
|
+
res,
|
|
620
|
+
performance,
|
|
621
|
+
componentData,
|
|
622
|
+
}: {
|
|
623
|
+
api: ApiRequest
|
|
624
|
+
res: Response
|
|
625
|
+
performance: ApiPerformance
|
|
626
|
+
componentData: ComponentData
|
|
627
|
+
}) {
|
|
529
628
|
const parseChunk = (chunk: string) => {
|
|
530
629
|
const event = chunk.match(/event: (.*)/)?.[1] ?? 'message'
|
|
531
630
|
const data = chunk.match(/data: (.*)/)?.[1] ?? ''
|
|
@@ -554,6 +653,7 @@ export function createAPI(
|
|
|
554
653
|
parseChunk,
|
|
555
654
|
parseChunksForData: (chunks) => [...chunks],
|
|
556
655
|
delimiters: ['\n\n', '\r\n\r\n'],
|
|
656
|
+
componentData,
|
|
557
657
|
})
|
|
558
658
|
}
|
|
559
659
|
|
|
@@ -565,7 +665,8 @@ export function createAPI(
|
|
|
565
665
|
useTextDecoder,
|
|
566
666
|
parseChunk,
|
|
567
667
|
parseChunksForData,
|
|
568
|
-
delimiters, // There can be various delimiters for the same stream. SSE might use both \n\n and \r\n\r\n
|
|
668
|
+
delimiters, // There can be various delimiters for the same stream. SSE might use both \n\n and \r\n\r\n,
|
|
669
|
+
componentData,
|
|
569
670
|
}: {
|
|
570
671
|
api: ApiRequest
|
|
571
672
|
res: Response
|
|
@@ -575,6 +676,7 @@ export function createAPI(
|
|
|
575
676
|
parseChunk: (chunk: any) => any
|
|
576
677
|
parseChunksForData: (chunks: any[]) => any
|
|
577
678
|
delimiters?: string[]
|
|
679
|
+
componentData: ComponentData
|
|
578
680
|
}) {
|
|
579
681
|
const chunks: {
|
|
580
682
|
chunks: any[]
|
|
@@ -605,7 +707,12 @@ export function createAPI(
|
|
|
605
707
|
},
|
|
606
708
|
})
|
|
607
709
|
if ((api.client?.onMessage?.actions ?? []).length > 0) {
|
|
608
|
-
triggerActions(
|
|
710
|
+
triggerActions({
|
|
711
|
+
eventName: 'message',
|
|
712
|
+
api,
|
|
713
|
+
data: { body: parsedChunk },
|
|
714
|
+
componentData,
|
|
715
|
+
})
|
|
609
716
|
}
|
|
610
717
|
}
|
|
611
718
|
},
|
|
@@ -664,14 +771,20 @@ export function createAPI(
|
|
|
664
771
|
cause: chunks.chunks.join(''),
|
|
665
772
|
})
|
|
666
773
|
}
|
|
667
|
-
return endResponse(api, status, performance)
|
|
774
|
+
return endResponse({ api, apiStatus: status, componentData, performance })
|
|
668
775
|
}
|
|
669
776
|
|
|
670
|
-
function endResponse(
|
|
671
|
-
api
|
|
672
|
-
apiStatus
|
|
673
|
-
|
|
674
|
-
|
|
777
|
+
function endResponse({
|
|
778
|
+
api,
|
|
779
|
+
apiStatus,
|
|
780
|
+
componentData,
|
|
781
|
+
performance,
|
|
782
|
+
}: {
|
|
783
|
+
api: ApiRequest
|
|
784
|
+
apiStatus: ApiStatus
|
|
785
|
+
componentData: ComponentData
|
|
786
|
+
performance: ApiPerformance
|
|
787
|
+
}) {
|
|
675
788
|
performance.responseEnd = Date.now()
|
|
676
789
|
|
|
677
790
|
const data = {
|
|
@@ -692,7 +805,7 @@ export function createAPI(
|
|
|
692
805
|
status: data.status,
|
|
693
806
|
headers: data.headers,
|
|
694
807
|
},
|
|
695
|
-
formulaContext: getFormulaContext(api),
|
|
808
|
+
formulaContext: getFormulaContext(api, componentData),
|
|
696
809
|
errorFormula: api.isError,
|
|
697
810
|
performance,
|
|
698
811
|
})
|
|
@@ -702,11 +815,11 @@ export function createAPI(
|
|
|
702
815
|
data.body = apiStatus.error
|
|
703
816
|
}
|
|
704
817
|
|
|
705
|
-
apiError(api, data, performance)
|
|
706
|
-
triggerActions('failed', api, data)
|
|
818
|
+
apiError({ api, componentData, data, performance })
|
|
819
|
+
triggerActions({ eventName: 'failed', api, componentData, data })
|
|
707
820
|
} else {
|
|
708
|
-
apiSuccess(api, data, performance)
|
|
709
|
-
triggerActions('success', api, data)
|
|
821
|
+
apiSuccess({ api, componentData, data, performance })
|
|
822
|
+
triggerActions({ eventName: 'success', api, componentData, data })
|
|
710
823
|
}
|
|
711
824
|
}
|
|
712
825
|
|
|
@@ -741,9 +854,9 @@ export function createAPI(
|
|
|
741
854
|
|
|
742
855
|
// eslint-disable-next-line prefer-const
|
|
743
856
|
payloadSignal = ctx.dataSignal.map((_) => {
|
|
744
|
-
const payloadContext = getFormulaContext(api)
|
|
857
|
+
const payloadContext = getFormulaContext(api, initialComponentData)
|
|
745
858
|
return {
|
|
746
|
-
request: constructRequest(api),
|
|
859
|
+
request: constructRequest(api, initialComponentData),
|
|
747
860
|
api: getApiForComparison(api),
|
|
748
861
|
autoFetch: api.autoFetch
|
|
749
862
|
? applyFormula(api.autoFetch, payloadContext)
|
|
@@ -752,7 +865,7 @@ export function createAPI(
|
|
|
752
865
|
}
|
|
753
866
|
})
|
|
754
867
|
payloadSignal.subscribe(async (_) => {
|
|
755
|
-
const { url, requestSettings } = constructRequest(api)
|
|
868
|
+
const { url, requestSettings } = constructRequest(api, initialComponentData)
|
|
756
869
|
// Ensure we only use caching if the page is currently loading
|
|
757
870
|
const cacheMatch =
|
|
758
871
|
// We lookup the API from cache as long as autofetch is defined (and not statically falsy)
|
|
@@ -767,42 +880,54 @@ export function createAPI(
|
|
|
767
880
|
|
|
768
881
|
if (cacheMatch) {
|
|
769
882
|
if (cacheMatch.error) {
|
|
770
|
-
apiError(
|
|
883
|
+
apiError({
|
|
771
884
|
api,
|
|
772
|
-
{
|
|
885
|
+
data: {
|
|
773
886
|
body: cacheMatch.error,
|
|
774
887
|
status: cacheMatch.response?.status,
|
|
775
888
|
headers: cacheMatch.response?.headers ?? undefined,
|
|
776
889
|
},
|
|
777
|
-
{
|
|
890
|
+
performance: {
|
|
778
891
|
requestStart:
|
|
779
892
|
cacheMatch.response?.performance?.requestStart ?? null,
|
|
780
893
|
responseStart:
|
|
781
894
|
cacheMatch.response?.performance?.responseStart ?? null,
|
|
782
895
|
responseEnd: cacheMatch.response?.performance?.responseEnd ?? null,
|
|
783
896
|
},
|
|
784
|
-
|
|
897
|
+
componentData: initialComponentData,
|
|
898
|
+
})
|
|
785
899
|
} else {
|
|
786
|
-
apiSuccess(
|
|
900
|
+
apiSuccess({
|
|
787
901
|
api,
|
|
788
|
-
{
|
|
902
|
+
data: {
|
|
789
903
|
body: cacheMatch.data,
|
|
790
904
|
status: cacheMatch.response?.status,
|
|
791
905
|
headers: cacheMatch.response?.headers ?? undefined,
|
|
792
906
|
},
|
|
793
|
-
{
|
|
907
|
+
performance: {
|
|
794
908
|
requestStart:
|
|
795
909
|
cacheMatch.response?.performance?.requestStart ?? null,
|
|
796
910
|
responseStart:
|
|
797
911
|
cacheMatch.response?.performance?.responseStart ?? null,
|
|
798
912
|
responseEnd: cacheMatch.response?.performance?.responseEnd ?? null,
|
|
799
913
|
},
|
|
800
|
-
|
|
914
|
+
componentData: initialComponentData,
|
|
915
|
+
})
|
|
801
916
|
}
|
|
802
917
|
} else {
|
|
803
|
-
if (
|
|
918
|
+
if (
|
|
919
|
+
applyFormula(
|
|
920
|
+
api.autoFetch,
|
|
921
|
+
getFormulaContext(api, initialComponentData),
|
|
922
|
+
)
|
|
923
|
+
) {
|
|
804
924
|
// Execute will set the initial status of the api in the dataSignal
|
|
805
|
-
await execute(
|
|
925
|
+
await execute({
|
|
926
|
+
api,
|
|
927
|
+
url,
|
|
928
|
+
requestSettings,
|
|
929
|
+
componentData: initialComponentData,
|
|
930
|
+
})
|
|
806
931
|
} else {
|
|
807
932
|
ctx.dataSignal.update((data) => {
|
|
808
933
|
return {
|
|
@@ -822,24 +947,7 @@ export function createAPI(
|
|
|
822
947
|
})
|
|
823
948
|
|
|
824
949
|
return {
|
|
825
|
-
fetch: ({
|
|
826
|
-
actionInputs,
|
|
827
|
-
actionModels,
|
|
828
|
-
}: {
|
|
829
|
-
actionInputs?: Record<
|
|
830
|
-
string,
|
|
831
|
-
| ValueOperationValue
|
|
832
|
-
| {
|
|
833
|
-
name: string
|
|
834
|
-
formula?: Formula
|
|
835
|
-
}
|
|
836
|
-
>
|
|
837
|
-
actionModels?: {
|
|
838
|
-
onCompleted: ActionModel[]
|
|
839
|
-
onFailed: ActionModel[]
|
|
840
|
-
onMessage: ActionModel[]
|
|
841
|
-
}
|
|
842
|
-
}) => {
|
|
950
|
+
fetch: ({ actionInputs, actionModels, componentData }) => {
|
|
843
951
|
// Inputs might already be evaluated. If they are we add them as a value formula to be evaluated later.
|
|
844
952
|
const inputs = Object.entries(actionInputs ?? {}).reduce<
|
|
845
953
|
Record<
|
|
@@ -891,18 +999,26 @@ export function createAPI(
|
|
|
891
999
|
},
|
|
892
1000
|
}
|
|
893
1001
|
|
|
894
|
-
const { url, requestSettings } = constructRequest(
|
|
1002
|
+
const { url, requestSettings } = constructRequest(
|
|
1003
|
+
apiWithInputsAndActions,
|
|
1004
|
+
componentData,
|
|
1005
|
+
)
|
|
895
1006
|
|
|
896
|
-
return execute(
|
|
1007
|
+
return execute({
|
|
1008
|
+
api: apiWithInputsAndActions,
|
|
1009
|
+
url,
|
|
1010
|
+
requestSettings,
|
|
1011
|
+
componentData,
|
|
1012
|
+
})
|
|
897
1013
|
},
|
|
898
|
-
update: (newApi
|
|
1014
|
+
update: (newApi, componentData) => {
|
|
899
1015
|
api = newApi
|
|
900
|
-
const updateContext = getFormulaContext(api)
|
|
1016
|
+
const updateContext = getFormulaContext(api, componentData)
|
|
901
1017
|
const autoFetch =
|
|
902
1018
|
api.autoFetch && applyFormula(api.autoFetch, updateContext)
|
|
903
1019
|
if (autoFetch) {
|
|
904
1020
|
payloadSignal?.set({
|
|
905
|
-
request: constructRequest(newApi),
|
|
1021
|
+
request: constructRequest(newApi, componentData),
|
|
906
1022
|
api: getApiForComparison(newApi),
|
|
907
1023
|
autoFetch,
|
|
908
1024
|
proxy: applyFormula(
|
|
@@ -912,7 +1028,7 @@ export function createAPI(
|
|
|
912
1028
|
})
|
|
913
1029
|
}
|
|
914
1030
|
},
|
|
915
|
-
triggerActions: () => {
|
|
1031
|
+
triggerActions: (componentData) => {
|
|
916
1032
|
const apiData = ctx.dataSignal.get().Apis?.[api.name]
|
|
917
1033
|
if (
|
|
918
1034
|
apiData === undefined ||
|
|
@@ -921,13 +1037,23 @@ export function createAPI(
|
|
|
921
1037
|
return
|
|
922
1038
|
}
|
|
923
1039
|
if (apiData.error) {
|
|
924
|
-
triggerActions(
|
|
925
|
-
|
|
926
|
-
|
|
1040
|
+
triggerActions({
|
|
1041
|
+
eventName: 'failed',
|
|
1042
|
+
api,
|
|
1043
|
+
data: {
|
|
1044
|
+
body: apiData.error,
|
|
1045
|
+
status: apiData.response?.status,
|
|
1046
|
+
},
|
|
1047
|
+
componentData,
|
|
927
1048
|
})
|
|
928
1049
|
} else {
|
|
929
|
-
triggerActions(
|
|
930
|
-
|
|
1050
|
+
triggerActions({
|
|
1051
|
+
eventName: 'success',
|
|
1052
|
+
api,
|
|
1053
|
+
data: {
|
|
1054
|
+
body: apiData.data,
|
|
1055
|
+
},
|
|
1056
|
+
componentData,
|
|
931
1057
|
})
|
|
932
1058
|
}
|
|
933
1059
|
},
|