@player-ui/async-node-plugin 0.15.3-next.3 → 0.15.4--canary.881.37421
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/AsyncNodePlugin.native.js +3284 -2679
- package/dist/AsyncNodePlugin.native.js.map +1 -1
- package/dist/cjs/index.cjs +214 -69
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.legacy-esm.js +207 -60
- package/dist/index.mjs +207 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
- package/src/AsyncNodeError.ts +30 -0
- package/src/__tests__/index.test.ts +277 -4
- package/src/index.ts +189 -68
- package/src/internal-types.ts +30 -0
- package/src/utils/__tests__/getNodeFromError.test.ts +219 -0
- package/src/utils/__tests__/isAsyncPlayerError.test.ts +33 -0
- package/src/utils/getNodeFromError.ts +34 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/isAsyncPlayerError.ts +8 -0
- package/types/AsyncNodeError.d.ts +13 -0
- package/types/index.d.ts +3 -18
- package/types/internal-types.d.ts +29 -0
- package/types/utils/getNodeFromError.d.ts +5 -0
- package/types/utils/index.d.ts +2 -0
- package/types/utils/isAsyncPlayerError.d.ts +4 -0
package/dist/index.legacy-esm.js
CHANGED
|
@@ -3,32 +3,22 @@ import { NodeType as NodeType5, getNodeID } from "@player-ui/player";
|
|
|
3
3
|
import { AsyncSeriesBailHook, SyncBailHook } from "tapable-ts";
|
|
4
4
|
import queueMicrotask from "queue-microtask";
|
|
5
5
|
|
|
6
|
-
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/
|
|
7
|
-
import { Builder } from "@player-ui/player";
|
|
8
|
-
var asyncTransform = (assetId, wrapperAssetType, asset, flatten, path = ["values"]) => {
|
|
9
|
-
const id = "async-" + assetId;
|
|
10
|
-
const asyncNode = Builder.asyncNode(id, flatten);
|
|
11
|
-
let multiNode;
|
|
12
|
-
let assetNode;
|
|
13
|
-
if (asset) {
|
|
14
|
-
assetNode = Builder.assetWrapper(asset);
|
|
15
|
-
multiNode = Builder.multiNode(assetNode, asyncNode);
|
|
16
|
-
} else {
|
|
17
|
-
multiNode = Builder.multiNode(asyncNode);
|
|
18
|
-
}
|
|
19
|
-
const wrapperAsset = Builder.asset({
|
|
20
|
-
id: wrapperAssetType + "-" + id,
|
|
21
|
-
type: wrapperAssetType
|
|
22
|
-
});
|
|
23
|
-
Builder.addChild(wrapperAsset, path, multiNode);
|
|
24
|
-
return wrapperAsset;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/createAsyncTransform.ts
|
|
6
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/AsyncNodeError.ts
|
|
28
7
|
import {
|
|
29
|
-
|
|
30
|
-
NodeType as NodeType4
|
|
8
|
+
ErrorSeverity
|
|
31
9
|
} from "@player-ui/player";
|
|
10
|
+
var ASYNC_ERROR_TYPE = "ASYNC-PLUGIN";
|
|
11
|
+
var AsyncNodeError = class extends Error {
|
|
12
|
+
constructor(node, message, cause) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.cause = cause;
|
|
15
|
+
this.type = ASYNC_ERROR_TYPE;
|
|
16
|
+
this.severity = ErrorSeverity.ERROR;
|
|
17
|
+
this.metadata = {
|
|
18
|
+
node
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
};
|
|
32
22
|
|
|
33
23
|
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/utils/extractNodeFromPath.ts
|
|
34
24
|
var getMatchValue = (pathA, pathB) => {
|
|
@@ -125,7 +115,59 @@ var requiresAssetWrapper = (node) => {
|
|
|
125
115
|
return node.value.type === NodeType3.Asset;
|
|
126
116
|
};
|
|
127
117
|
|
|
118
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/utils/isAsyncPlayerError.ts
|
|
119
|
+
var isAsyncPlayerError = (error) => {
|
|
120
|
+
return error.type === ASYNC_ERROR_TYPE;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/utils/getNodeFromError.ts
|
|
124
|
+
import { ErrorTypes } from "@player-ui/player";
|
|
125
|
+
var getNodeFromError = (playerError, context) => {
|
|
126
|
+
if (playerError.type === ErrorTypes.RENDER) {
|
|
127
|
+
const { assetId } = playerError.metadata ?? {};
|
|
128
|
+
if (typeof assetId !== "string") {
|
|
129
|
+
return void 0;
|
|
130
|
+
}
|
|
131
|
+
return context.assetIdCache.get(assetId);
|
|
132
|
+
}
|
|
133
|
+
if (playerError.type === ErrorTypes.VIEW) {
|
|
134
|
+
const { node } = playerError.metadata ?? {};
|
|
135
|
+
if (typeof node === "object" && node !== null && !Array.isArray(node)) {
|
|
136
|
+
return node;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (isAsyncPlayerError(playerError) && playerError.metadata !== void 0) {
|
|
140
|
+
return context.asyncNodeCache.get(playerError.metadata.node.id)?.asyncNode;
|
|
141
|
+
}
|
|
142
|
+
return void 0;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/transform.ts
|
|
146
|
+
import { Builder } from "@player-ui/player";
|
|
147
|
+
var asyncTransform = (assetId, wrapperAssetType, asset, flatten, path = ["values"]) => {
|
|
148
|
+
const id = "async-" + assetId;
|
|
149
|
+
const asyncNode = Builder.asyncNode(id, flatten);
|
|
150
|
+
let multiNode;
|
|
151
|
+
let assetNode;
|
|
152
|
+
if (asset) {
|
|
153
|
+
assetNode = Builder.assetWrapper(asset);
|
|
154
|
+
multiNode = Builder.multiNode(assetNode, asyncNode);
|
|
155
|
+
} else {
|
|
156
|
+
multiNode = Builder.multiNode(asyncNode);
|
|
157
|
+
}
|
|
158
|
+
const wrapperAsset = Builder.asset({
|
|
159
|
+
id: wrapperAssetType + "-" + id,
|
|
160
|
+
type: wrapperAssetType
|
|
161
|
+
});
|
|
162
|
+
Builder.addChild(wrapperAsset, path, multiNode);
|
|
163
|
+
return wrapperAsset;
|
|
164
|
+
};
|
|
165
|
+
|
|
128
166
|
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/async-node/core/src/createAsyncTransform.ts
|
|
167
|
+
import {
|
|
168
|
+
Builder as Builder2,
|
|
169
|
+
NodeType as NodeType4
|
|
170
|
+
} from "@player-ui/player";
|
|
129
171
|
var defaultGetNodeId = (node) => {
|
|
130
172
|
return `async-${node.value.id}`;
|
|
131
173
|
};
|
|
@@ -235,8 +277,8 @@ var AsyncNodePluginPlugin = class {
|
|
|
235
277
|
* @param options Options provided for node resolution, including a potential parseNode function to process the result.
|
|
236
278
|
* @param view The view instance where the node resides. This can be undefined if the view is not currently active.
|
|
237
279
|
*/
|
|
238
|
-
parseNodeAndUpdate(node, context, result,
|
|
239
|
-
let parsedNode =
|
|
280
|
+
parseNodeAndUpdate(node, context, result, parseFunction) {
|
|
281
|
+
let parsedNode = parseFunction && result ? parseFunction(result) : void 0;
|
|
240
282
|
if (parsedNode && node.onValueReceived) {
|
|
241
283
|
parsedNode = node.onValueReceived(parsedNode);
|
|
242
284
|
}
|
|
@@ -252,16 +294,30 @@ var AsyncNodePluginPlugin = class {
|
|
|
252
294
|
* @param view The view instance where the node resides. This can be undefined if the view is not currently active.
|
|
253
295
|
*/
|
|
254
296
|
handleAsyncUpdate(node, context, newNode) {
|
|
255
|
-
const {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
297
|
+
const { asyncNodeCache: asyncNodeInfo, viewController } = context;
|
|
298
|
+
const entry = asyncNodeInfo.get(node.id);
|
|
299
|
+
if (!entry) {
|
|
300
|
+
throw new Error("Failed to update async content. Cache entry not found");
|
|
301
|
+
}
|
|
302
|
+
if (entry.resolvedContent !== newNode) {
|
|
303
|
+
entry.resolvedContent = newNode ? newNode : entry.asyncNode;
|
|
304
|
+
viewController.updateViewAST(entry.updateNodes);
|
|
260
305
|
}
|
|
261
306
|
}
|
|
262
|
-
hasValidMapping(
|
|
263
|
-
|
|
264
|
-
|
|
307
|
+
hasValidMapping(cacheEntry) {
|
|
308
|
+
return cacheEntry.resolvedContent !== void 0 && cacheEntry.resolvedContent !== cacheEntry.asyncNode;
|
|
309
|
+
}
|
|
310
|
+
getOrCreateAsyncNodeCacheEntry(node, context) {
|
|
311
|
+
const { asyncNodeCache: asyncNodeInfo } = context;
|
|
312
|
+
let entry = asyncNodeInfo.get(node.id);
|
|
313
|
+
if (!entry) {
|
|
314
|
+
entry = {
|
|
315
|
+
asyncNode: node,
|
|
316
|
+
updateNodes: /* @__PURE__ */ new Set()
|
|
317
|
+
};
|
|
318
|
+
asyncNodeInfo.set(node.id, entry);
|
|
319
|
+
}
|
|
320
|
+
return entry;
|
|
265
321
|
}
|
|
266
322
|
/**
|
|
267
323
|
* Handles the asynchronous API integration for resolving nodes.
|
|
@@ -270,16 +326,24 @@ var AsyncNodePluginPlugin = class {
|
|
|
270
326
|
* @param view
|
|
271
327
|
*/
|
|
272
328
|
applyResolver(resolver, context) {
|
|
329
|
+
const { assetIdCache } = context;
|
|
330
|
+
resolver.hooks.afterNodeUpdate.tap(this.name, (original, _, update) => {
|
|
331
|
+
if (update.node.type !== NodeType5.Asset && update.node.type !== NodeType5.View) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
assetIdCache.set(update.value.id, original);
|
|
335
|
+
});
|
|
273
336
|
resolver.hooks.beforeResolve.tap(this.name, (node, options) => {
|
|
274
337
|
if (!this.isAsync(node)) {
|
|
275
338
|
return node === null ? node : this.resolveAsyncChildren(node, context);
|
|
276
339
|
}
|
|
340
|
+
const entry = this.getOrCreateAsyncNodeCacheEntry(node, context);
|
|
277
341
|
if (options.node) {
|
|
278
|
-
|
|
342
|
+
entry.updateNodes = /* @__PURE__ */ new Set([options.node]);
|
|
343
|
+
context.generatedByMap.set(options.node, node.id);
|
|
279
344
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
return this.resolveAsyncChildren(resolvedNode, context);
|
|
345
|
+
if (entry.resolvedContent !== void 0) {
|
|
346
|
+
return this.resolveAsyncChildren(entry.resolvedContent, context);
|
|
283
347
|
}
|
|
284
348
|
if (context.inProgressNodes.has(node.id)) {
|
|
285
349
|
return node;
|
|
@@ -303,16 +367,22 @@ var AsyncNodePluginPlugin = class {
|
|
|
303
367
|
let index = 0;
|
|
304
368
|
while (index < node.values.length) {
|
|
305
369
|
const childNode = node.values[index];
|
|
306
|
-
if (childNode?.type !== NodeType5.Async
|
|
370
|
+
if (childNode?.type !== NodeType5.Async) {
|
|
307
371
|
index++;
|
|
308
372
|
continue;
|
|
309
373
|
}
|
|
310
|
-
const
|
|
374
|
+
const entry = this.getOrCreateAsyncNodeCacheEntry(childNode, context);
|
|
375
|
+
if (!this.hasValidMapping(entry)) {
|
|
376
|
+
index++;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
const mappedNode = entry.resolvedContent;
|
|
311
380
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
312
381
|
if (mappedNode.type === NodeType5.MultiNode && childNode.flatten) {
|
|
313
382
|
mappedNode.values.forEach((v) => {
|
|
314
383
|
v.parent = node;
|
|
315
384
|
nodeSet.add(v);
|
|
385
|
+
context.originalParentMap.set(v, childNode);
|
|
316
386
|
});
|
|
317
387
|
node.values = [
|
|
318
388
|
...node.values.slice(0, index),
|
|
@@ -324,13 +394,21 @@ var AsyncNodePluginPlugin = class {
|
|
|
324
394
|
mappedNode.parent = node;
|
|
325
395
|
nodeSet.add(mappedNode);
|
|
326
396
|
}
|
|
327
|
-
|
|
397
|
+
entry.updateNodes = nodeSet;
|
|
398
|
+
for (const n of nodeSet) {
|
|
399
|
+
context.generatedByMap.set(n, childNode.id);
|
|
400
|
+
}
|
|
328
401
|
}
|
|
329
402
|
} else if ("children" in node) {
|
|
330
403
|
node.children?.forEach((c) => {
|
|
331
|
-
while (c.value.type === NodeType5.Async
|
|
332
|
-
const
|
|
333
|
-
|
|
404
|
+
while (c.value.type === NodeType5.Async) {
|
|
405
|
+
const entry = this.getOrCreateAsyncNodeCacheEntry(c.value, context);
|
|
406
|
+
if (!this.hasValidMapping(entry)) {
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
const mappedNode = entry.resolvedContent;
|
|
410
|
+
entry.updateNodes = /* @__PURE__ */ new Set([mappedNode]);
|
|
411
|
+
context.generatedByMap.set(mappedNode, c.value.id);
|
|
334
412
|
c.value = mappedNode;
|
|
335
413
|
c.value.parent = node;
|
|
336
414
|
}
|
|
@@ -343,27 +421,27 @@ var AsyncNodePluginPlugin = class {
|
|
|
343
421
|
const result = await this.basePlugin?.hooks.onAsyncNode.call(
|
|
344
422
|
node,
|
|
345
423
|
(result2) => {
|
|
346
|
-
this.parseNodeAndUpdate(node, context, result2, options);
|
|
424
|
+
this.parseNodeAndUpdate(node, context, result2, options.parseNode);
|
|
347
425
|
}
|
|
348
426
|
);
|
|
349
427
|
context.inProgressNodes.delete(node.id);
|
|
350
|
-
this.parseNodeAndUpdate(node, context, result, options);
|
|
428
|
+
this.parseNodeAndUpdate(node, context, result, options.parseNode);
|
|
351
429
|
} catch (e) {
|
|
352
|
-
const
|
|
353
|
-
const
|
|
354
|
-
if (
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
430
|
+
const cause = e instanceof Error ? e : new Error(String(e));
|
|
431
|
+
const playerState = this.basePlugin?.getPlayerInstance()?.getState();
|
|
432
|
+
if (playerState?.status !== "in-progress") {
|
|
433
|
+
options.logger?.warn(
|
|
434
|
+
"[AsyncNodePlugin]: An error occured during async node resolution, but the player instance is no londer running. Exception: ",
|
|
435
|
+
cause
|
|
436
|
+
);
|
|
359
437
|
return;
|
|
360
438
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
error
|
|
439
|
+
const error = new AsyncNodeError(
|
|
440
|
+
node,
|
|
441
|
+
"An error occured during async node resolution. See cause for details.",
|
|
442
|
+
cause
|
|
364
443
|
);
|
|
365
|
-
|
|
366
|
-
this.parseNodeAndUpdate(node, context, result, options);
|
|
444
|
+
playerState.controllers.error.captureError(error);
|
|
367
445
|
}
|
|
368
446
|
}
|
|
369
447
|
isAsync(node) {
|
|
@@ -409,15 +487,84 @@ var AsyncNodePluginPlugin = class {
|
|
|
409
487
|
view.hooks.parser.tap("async", this.applyParser.bind(this));
|
|
410
488
|
}
|
|
411
489
|
applyPlayer(player) {
|
|
490
|
+
let currentContext = void 0;
|
|
491
|
+
let parser = void 0;
|
|
492
|
+
player.hooks.errorController.tap("async", (errorController) => {
|
|
493
|
+
errorController.hooks.onError.tap("async", (playerError) => {
|
|
494
|
+
if (currentContext === void 0) {
|
|
495
|
+
return void 0;
|
|
496
|
+
}
|
|
497
|
+
const tryHandleError = (asyncNode) => {
|
|
498
|
+
if (this.basePlugin === void 0) {
|
|
499
|
+
player.logger.warn(
|
|
500
|
+
`[AsyncNodePlugin]: No plugin detected. Error handling will fail`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
let result = void 0;
|
|
504
|
+
result = this.basePlugin?.hooks.onAsyncNodeError.call(
|
|
505
|
+
playerError,
|
|
506
|
+
asyncNode
|
|
507
|
+
);
|
|
508
|
+
if (result === void 0) {
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
511
|
+
player.logger?.warn(
|
|
512
|
+
"[AsyncNodePlugin]: Async node handling failed and resolved with a fallback. Cause:",
|
|
513
|
+
playerError.message
|
|
514
|
+
);
|
|
515
|
+
currentContext.inProgressNodes.delete(asyncNode.id);
|
|
516
|
+
this.parseNodeAndUpdate(
|
|
517
|
+
asyncNode,
|
|
518
|
+
currentContext,
|
|
519
|
+
result,
|
|
520
|
+
parser?.parseObject.bind(parser)
|
|
521
|
+
);
|
|
522
|
+
return true;
|
|
523
|
+
};
|
|
524
|
+
const getNextNode = (node2) => {
|
|
525
|
+
const parent = currentContext?.originalParentMap.get(node2) ?? node2.parent;
|
|
526
|
+
if (!parent) {
|
|
527
|
+
return void 0;
|
|
528
|
+
}
|
|
529
|
+
return this.isAsync(parent) ? currentContext?.asyncNodeCache.get(parent.id)?.asyncNode : parent;
|
|
530
|
+
};
|
|
531
|
+
let node = getNodeFromError(playerError, currentContext);
|
|
532
|
+
if (node?.type === NodeType5.Async && tryHandleError(node)) {
|
|
533
|
+
return true;
|
|
534
|
+
}
|
|
535
|
+
while (node !== void 0) {
|
|
536
|
+
const generatedBy = currentContext.generatedByMap.get(node);
|
|
537
|
+
if (generatedBy) {
|
|
538
|
+
const entry = currentContext.asyncNodeCache.get(generatedBy);
|
|
539
|
+
if (!entry) {
|
|
540
|
+
node = getNextNode(node);
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
const { asyncNode } = entry;
|
|
544
|
+
if (tryHandleError(asyncNode)) {
|
|
545
|
+
return true;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
node = getNextNode(node);
|
|
549
|
+
}
|
|
550
|
+
return void 0;
|
|
551
|
+
});
|
|
552
|
+
});
|
|
412
553
|
player.hooks.viewController.tap("async", (viewController) => {
|
|
413
554
|
viewController.hooks.view.tap("async", (view) => {
|
|
555
|
+
view.hooks.parser.tap(this.name, (p) => {
|
|
556
|
+
parser = p;
|
|
557
|
+
});
|
|
414
558
|
const context = {
|
|
415
|
-
nodeResolveCache: /* @__PURE__ */ new Map(),
|
|
416
559
|
inProgressNodes: /* @__PURE__ */ new Set(),
|
|
417
560
|
view,
|
|
418
561
|
viewController,
|
|
419
|
-
|
|
562
|
+
generatedByMap: /* @__PURE__ */ new Map(),
|
|
563
|
+
assetIdCache: /* @__PURE__ */ new Map(),
|
|
564
|
+
asyncNodeCache: /* @__PURE__ */ new Map(),
|
|
565
|
+
originalParentMap: /* @__PURE__ */ new Map()
|
|
420
566
|
};
|
|
567
|
+
currentContext = context;
|
|
421
568
|
view.hooks.resolver.tap("async", (resolver) => {
|
|
422
569
|
this.applyResolver(resolver, context);
|
|
423
570
|
});
|