@player-ui/player 0.13.0 → 0.14.0-next.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.
@@ -85,7 +85,7 @@ var parse = (path) => {
85
85
  next();
86
86
  }
87
87
  };
88
- const identifier = () => {
88
+ const identifier = (allowBoolValue = false) => {
89
89
  if (!isIdentifierChar(ch)) {
90
90
  return;
91
91
  }
@@ -96,6 +96,14 @@ var parse = (path) => {
96
96
  }
97
97
  value += ch;
98
98
  }
99
+ if (allowBoolValue) {
100
+ if (value === "true") {
101
+ return toValue(true);
102
+ }
103
+ if (value === "false") {
104
+ return toValue(false);
105
+ }
106
+ }
99
107
  if (value) {
100
108
  const maybeNumber = Number(value);
101
109
  value = isNaN(maybeNumber) ? value : maybeNumber;
@@ -143,7 +151,7 @@ var parse = (path) => {
143
151
  return modelRef;
144
152
  }
145
153
  };
146
- const simpleSegment = () => nestedPath() ?? expression() ?? identifier();
154
+ const simpleSegment = (allowBoolValue = false) => nestedPath() ?? expression() ?? identifier(allowBoolValue);
147
155
  const segment = () => {
148
156
  const segments = [];
149
157
  let nextSegment = simpleSegment();
@@ -156,7 +164,7 @@ var parse = (path) => {
156
164
  }
157
165
  return toConcatenatedNode(segments);
158
166
  };
159
- const optionallyQuotedSegment = () => {
167
+ const optionallyQuotedSegment = (allowBoolValue = false) => {
160
168
  whitespace();
161
169
  if (ch === SINGLE_QUOTE || ch === DOUBLE_QUOTE) {
162
170
  const singleQuote = ch === SINGLE_QUOTE;
@@ -165,7 +173,7 @@ var parse = (path) => {
165
173
  next(singleQuote ? SINGLE_QUOTE : DOUBLE_QUOTE);
166
174
  return id;
167
175
  }
168
- return simpleSegment();
176
+ return simpleSegment(allowBoolValue);
169
177
  };
170
178
  const equals = () => {
171
179
  if (ch !== EQUALS) {
@@ -185,7 +193,7 @@ var parse = (path) => {
185
193
  whitespace();
186
194
  if (equals()) {
187
195
  whitespace();
188
- const second = optionallyQuotedSegment();
196
+ const second = optionallyQuotedSegment(true);
189
197
  value = toQuery(value, second);
190
198
  whitespace();
191
199
  }
@@ -387,7 +395,9 @@ function resolveBindingAST(bindingPathNode, options, hooks) {
387
395
  appendPathSegments(getValueForNode(resolvedNode));
388
396
  break;
389
397
  case "Value":
390
- appendPathSegments(resolvedNode.value);
398
+ appendPathSegments(
399
+ typeof resolvedNode.value === "boolean" ? String(resolvedNode.value) : resolvedNode.value
400
+ );
391
401
  break;
392
402
  case "Query": {
393
403
  const objToQuery = options.getValue(context.path) ?? [];
@@ -2689,24 +2699,7 @@ var EMPTY_NODE = {
2689
2699
  var Parser = class {
2690
2700
  constructor() {
2691
2701
  this.hooks = {
2692
- /**
2693
- * A hook to interact with an object _before_ parsing it into an AST
2694
- *
2695
- * @param value - The object we're are about to parse
2696
- * @returns - A new value to parse.
2697
- * If undefined, the original value is used.
2698
- * If null, we stop parsing this node.
2699
- */
2700
2702
  onParseObject: new SyncWaterfallHook4(),
2701
- /**
2702
- * A callback to interact with an AST _after_ we parse it into the AST
2703
- *
2704
- * @param value - The object we parsed
2705
- * @param node - The AST node we generated
2706
- * @returns - A new AST node to use
2707
- * If undefined, the original value is used.
2708
- * If null, we ignore this node all together
2709
- */
2710
2703
  onCreateASTNode: new SyncWaterfallHook4(),
2711
2704
  parseNode: new SyncBailHook3()
2712
2705
  };
@@ -2861,27 +2854,13 @@ var withContext = (model) => {
2861
2854
  var Resolver = class {
2862
2855
  constructor(root, options) {
2863
2856
  this.hooks = {
2864
- /** A hook to allow skipping of the resolution tree for a specific node */
2865
2857
  skipResolve: new SyncWaterfallHook5(),
2866
- /** An event emitted before calculating the next update */
2867
2858
  beforeUpdate: new SyncHook3(),
2868
- /** An event emitted after calculating the next update */
2869
2859
  afterUpdate: new SyncHook3(),
2870
- /** The options passed to a node to resolve it to an object */
2871
2860
  resolveOptions: new SyncWaterfallHook5(),
2872
- /** A hook to transform the AST node into a new AST node before resolving it */
2873
2861
  beforeResolve: new SyncWaterfallHook5(),
2874
- /**
2875
- * A hook to transform an AST node into it's resolved value.
2876
- * This runs _before_ any children are resolved
2877
- */
2878
2862
  resolve: new SyncWaterfallHook5(),
2879
- /**
2880
- * A hook to transform the resolved value of an AST node.
2881
- * This runs _after_ all children nodes are resolved
2882
- */
2883
2863
  afterResolve: new SyncWaterfallHook5(),
2884
- /** Called at the very end of a node's tree being updated */
2885
2864
  afterNodeUpdate: new SyncHook3()
2886
2865
  };
2887
2866
  this.root = root;
@@ -2890,16 +2869,29 @@ var Resolver = class {
2890
2869
  this.ASTMap = /* @__PURE__ */ new Map();
2891
2870
  this.logger = options.logger;
2892
2871
  this.idCache = /* @__PURE__ */ new Set();
2872
+ this.AsyncIdMap = /* @__PURE__ */ new Map();
2893
2873
  }
2894
2874
  getSourceNode(convertedAST) {
2895
2875
  return this.ASTMap.get(convertedAST);
2896
2876
  }
2897
- update(changes) {
2877
+ update(changes, asyncChanges) {
2898
2878
  this.hooks.beforeUpdate.call(changes);
2899
2879
  const resolveCache = /* @__PURE__ */ new Map();
2900
2880
  this.idCache.clear();
2901
2881
  const prevASTMap = new Map(this.ASTMap);
2902
2882
  this.ASTMap.clear();
2883
+ const prevAsyncIdMap = new Map(this.AsyncIdMap);
2884
+ const nextAsyncIdMap = /* @__PURE__ */ new Map();
2885
+ asyncChanges?.forEach((id) => {
2886
+ let current = prevAsyncIdMap.get(id);
2887
+ while (current && prevASTMap.has(current)) {
2888
+ const next = prevASTMap.get(current);
2889
+ if (next && this.resolveCache.has(next)) {
2890
+ this.resolveCache.delete(next);
2891
+ }
2892
+ current = current.parent;
2893
+ }
2894
+ });
2903
2895
  const updated = this.computeTree(
2904
2896
  this.root,
2905
2897
  void 0,
@@ -2907,8 +2899,10 @@ var Resolver = class {
2907
2899
  resolveCache,
2908
2900
  toNodeResolveOptions(this.options),
2909
2901
  void 0,
2910
- prevASTMap
2902
+ prevASTMap,
2903
+ nextAsyncIdMap
2911
2904
  );
2905
+ this.AsyncIdMap = nextAsyncIdMap;
2912
2906
  this.resolveCache = resolveCache;
2913
2907
  this.hooks.afterUpdate.call(updated.value);
2914
2908
  return updated.value;
@@ -2953,7 +2947,7 @@ var Resolver = class {
2953
2947
  });
2954
2948
  return clonedNode;
2955
2949
  }
2956
- computeTree(node, rawParent, dataChanges, cacheUpdate, options, partiallyResolvedParent, prevASTMap) {
2950
+ computeTree(node, rawParent, dataChanges, cacheUpdate, options, partiallyResolvedParent, prevASTMap, nextAsyncIdMap) {
2957
2951
  const dependencyModel = new DependencyModel(options.data.model);
2958
2952
  dependencyModel.trackSubset("core");
2959
2953
  const depModelWithParser = withContext(
@@ -2979,18 +2973,6 @@ var Resolver = class {
2979
2973
  node,
2980
2974
  resolveOptions
2981
2975
  );
2982
- const clonedNode = {
2983
- ...this.cloneNode(node),
2984
- parent: partiallyResolvedParent
2985
- };
2986
- const resolvedAST = this.hooks.beforeResolve.call(
2987
- clonedNode,
2988
- resolveOptions
2989
- ) ?? {
2990
- type: "empty" /* Empty */
2991
- };
2992
- const isNestedMultiNodeWithAsync = resolvedAST.type === "multi-node" /* MultiNode */ && partiallyResolvedParent?.parent?.parent?.type === "multi-node" /* MultiNode */ && partiallyResolvedParent.parent.type === "value" /* Value */ && resolvedAST.parent?.type === "asset" /* Asset */ && resolvedAST.parent.value.id.includes("async");
2993
- const isNestedMultiNode = resolvedAST.type === "multi-node" /* MultiNode */ && partiallyResolvedParent?.parent?.type === "multi-node" /* MultiNode */ && partiallyResolvedParent.type === "value" /* Value */;
2994
2976
  if (previousResult && shouldUseLastValue) {
2995
2977
  const update2 = {
2996
2978
  ...previousResult,
@@ -3004,6 +2986,12 @@ var Resolver = class {
3004
2986
  updated: false
3005
2987
  };
3006
2988
  cacheUpdate.set(AST, resolvedUpdate);
2989
+ if (resolvedUpdate.node.type === "async" /* Async */) {
2990
+ nextAsyncIdMap.set(resolvedUpdate.node.id, resolvedUpdate.node);
2991
+ }
2992
+ for (const key of resolvedUpdate.node.asyncNodesResolved ?? []) {
2993
+ nextAsyncIdMap.set(key, resolvedUpdate.node);
2994
+ }
3007
2995
  const handleChildNode = (childNode) => {
3008
2996
  const originalChildNode = prevASTMap.get(childNode) ?? childNode;
3009
2997
  const previousChildResult = this.getPreviousResult(originalChildNode);
@@ -3028,10 +3016,22 @@ var Resolver = class {
3028
3016
  repopulateASTMapFromCache(previousResult, node, rawParent);
3029
3017
  return update2;
3030
3018
  }
3031
- if (isNestedMultiNodeWithAsync) {
3032
- resolvedAST.parent = partiallyResolvedParent.parent;
3033
- } else {
3034
- resolvedAST.parent = partiallyResolvedParent;
3019
+ const clonedNode = {
3020
+ ...this.cloneNode(node),
3021
+ parent: partiallyResolvedParent
3022
+ };
3023
+ const resolvedAST = this.hooks.beforeResolve.call(
3024
+ clonedNode,
3025
+ resolveOptions
3026
+ ) ?? {
3027
+ type: "empty" /* Empty */
3028
+ };
3029
+ resolvedAST.parent = partiallyResolvedParent;
3030
+ if (resolvedAST.type === "async" /* Async */) {
3031
+ nextAsyncIdMap.set(resolvedAST.id, resolvedAST);
3032
+ }
3033
+ for (const id of resolvedAST.asyncNodesResolved ?? []) {
3034
+ nextAsyncIdMap.set(id, resolvedAST);
3035
3035
  }
3036
3036
  resolveOptions.node = resolvedAST;
3037
3037
  this.ASTMap.set(resolvedAST, node);
@@ -3055,7 +3055,8 @@ var Resolver = class {
3055
3055
  cacheUpdate,
3056
3056
  resolveOptions,
3057
3057
  resolvedAST,
3058
- prevASTMap
3058
+ prevASTMap,
3059
+ nextAsyncIdMap
3059
3060
  );
3060
3061
  const {
3061
3062
  dependencies: childTreeDeps,
@@ -3081,9 +3082,8 @@ var Resolver = class {
3081
3082
  resolvedAST.children = newChildren;
3082
3083
  } else if (resolvedAST.type === "multi-node" /* MultiNode */) {
3083
3084
  const childValue = [];
3084
- const rawParentToPassIn = isNestedMultiNode ? partiallyResolvedParent?.parent : node;
3085
- const hasAsync = resolvedAST.values.map((value, index) => value.type === "async" /* Async */ ? index : -1).filter((index) => index !== -1);
3086
- const newValues = resolvedAST.values.map((mValue) => {
3085
+ const rawParentToPassIn = node;
3086
+ resolvedAST.values = resolvedAST.values.map((mValue) => {
3087
3087
  const mTree = this.computeTree(
3088
3088
  mValue,
3089
3089
  rawParentToPassIn,
@@ -3091,31 +3091,18 @@ var Resolver = class {
3091
3091
  cacheUpdate,
3092
3092
  resolveOptions,
3093
3093
  resolvedAST,
3094
- prevASTMap
3094
+ prevASTMap,
3095
+ nextAsyncIdMap
3095
3096
  );
3096
3097
  if (mTree.value !== void 0 && mTree.value !== null) {
3097
- if (mValue.type === "async" /* Async */ && mValue.flatten && mTree.value.asset && Array.isArray(mTree.value.asset.values)) {
3098
- unpackAndPush(mTree.value, childValue);
3099
- } else {
3100
- childValue.push(mTree.value);
3101
- }
3098
+ mTree.dependencies.forEach(
3099
+ (bindingDep) => childDependencies.add(bindingDep)
3100
+ );
3101
+ updated = updated || mTree.updated;
3102
+ childValue.push(mTree.value);
3102
3103
  }
3103
- mTree.dependencies.forEach(
3104
- (bindingDep) => childDependencies.add(bindingDep)
3105
- );
3106
- updated = updated || mTree.updated;
3107
3104
  return mTree.node;
3108
3105
  });
3109
- if (hasAsync.length > 0) {
3110
- const copy = newValues;
3111
- hasAsync.forEach((index) => {
3112
- if (copy[index])
3113
- copy.splice(index, 1, ...unpackNode(copy[index]));
3114
- });
3115
- resolvedAST.values = copy;
3116
- } else {
3117
- resolvedAST.values = newValues;
3118
- }
3119
3106
  resolved = childValue;
3120
3107
  }
3121
3108
  childDependencies.forEach(
@@ -3138,37 +3125,11 @@ var Resolver = class {
3138
3125
  ...childDependencies
3139
3126
  ])
3140
3127
  };
3141
- this.hooks.afterNodeUpdate.call(
3142
- node,
3143
- isNestedMultiNode ? partiallyResolvedParent?.parent : rawParent,
3144
- update
3145
- );
3128
+ this.hooks.afterNodeUpdate.call(node, rawParent, update);
3146
3129
  cacheUpdate.set(node, update);
3147
3130
  return update;
3148
3131
  }
3149
3132
  };
3150
- function unpackAndPush(item, initial) {
3151
- if (item.asset.values && Array.isArray(item.asset.values)) {
3152
- item.asset.values.forEach((i) => {
3153
- unpackAndPush(i, initial);
3154
- });
3155
- } else {
3156
- initial.push(item);
3157
- }
3158
- }
3159
- function unpackNode(item) {
3160
- const unpacked = [];
3161
- if ("children" in item && item.children?.[0]?.value.type === "asset" /* Asset */ && (item.children?.[0]?.value).children) {
3162
- if ((item.children?.[0]?.value).children?.[0]?.value.type === "multi-node" /* MultiNode */) {
3163
- ((item.children?.[0]?.value).children?.[0]?.value).values.forEach((value) => {
3164
- unpacked.push(value);
3165
- });
3166
- }
3167
- } else {
3168
- unpacked.push(item);
3169
- }
3170
- return unpacked;
3171
- }
3172
3133
 
3173
3134
  // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/view/view.ts
3174
3135
  var CrossfieldProvider = class {
@@ -3222,8 +3183,8 @@ var ViewInstance = class {
3222
3183
  this.initialView = initialView;
3223
3184
  this.resolverOptions = resolverOptions;
3224
3185
  }
3225
- updateAsync() {
3226
- const update = this.resolver?.update();
3186
+ updateAsync(asyncNode) {
3187
+ const update = this.resolver?.update(/* @__PURE__ */ new Set(), /* @__PURE__ */ new Set([asyncNode]));
3227
3188
  this.lastUpdate = update;
3228
3189
  this.hooks.onUpdate.call(update);
3229
3190
  }
@@ -3317,11 +3278,12 @@ var Builder = class _Builder {
3317
3278
  *
3318
3279
  * @param id - the id of async node. It should be identical for each async node
3319
3280
  */
3320
- static asyncNode(id, flatten2 = true) {
3281
+ static asyncNode(id, flatten2 = true, onValueReceived) {
3321
3282
  return {
3322
3283
  id,
3323
3284
  type: "async" /* Async */,
3324
3285
  flatten: flatten2,
3286
+ onValueReceived,
3325
3287
  value: {
3326
3288
  type: "value" /* Value */,
3327
3289
  value: {
@@ -3789,7 +3751,7 @@ var MultiNodePlugin = class {
3789
3751
  parser.hooks.parseNode.tap(
3790
3752
  "multi-node",
3791
3753
  (obj, nodeType, options, childOptions) => {
3792
- if (childOptions && !hasTemplateKey(childOptions.key) && Array.isArray(obj)) {
3754
+ if ((childOptions === void 0 || !hasTemplateKey(childOptions.key)) && Array.isArray(obj)) {
3793
3755
  const values = obj.map(
3794
3756
  (childVal) => parser.parseObject(childVal, "value" /* Value */, options)
3795
3757
  ).filter((child) => !!child);
@@ -3799,10 +3761,7 @@ var MultiNodePlugin = class {
3799
3761
  const multiNode = parser.createASTNode(
3800
3762
  {
3801
3763
  type: "multi-node" /* MultiNode */,
3802
- override: !hasTemplateValues(
3803
- childOptions.parentObj,
3804
- childOptions.key
3805
- ),
3764
+ override: childOptions !== void 0 && !hasTemplateValues(childOptions.parentObj, childOptions.key),
3806
3765
  values
3807
3766
  },
3808
3767
  obj
@@ -3815,7 +3774,7 @@ var MultiNodePlugin = class {
3815
3774
  v.parent = multiNode;
3816
3775
  });
3817
3776
  }
3818
- return [
3777
+ return childOptions === void 0 ? multiNode : [
3819
3778
  {
3820
3779
  path: [...childOptions.path, childOptions.key],
3821
3780
  value: multiNode