@foldkit/oxlint-plugin 0.15.2-canary.085b787da0a5 → 0.15.2-canary.3b49f516b024

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.
@@ -1 +1 @@
1
- {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EACL,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,QAAQ,EACd,MAAM,eAAe,CAAA;AAEtB,eAAO,MAAM,YAAY,SACjB,OAAO,SACN,MAAM,KACZ,IAAI,IAAI,QAAQ,CAAC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAOZ,CAAA;AAE5C,eAAO,MAAM,qBAAqB,SAC1B,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,mBAAyC,CAAA;AAE3D,eAAO,MAAM,eAAe,SAAU,OAAO,KAAG,IAAI,IAAI,MAAM,CAAC,aAM/B,CAAA;AAEhC,eAAO,MAAM,iBAAiB,SACtB,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,eAIe,CAAA;AAEjC,eAAO,MAAM,gBAAgB,SACrB,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,cAIc,CAAA;AAEhC,eAAO,MAAM,kBAAkB,SACvB,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,gBAIgB,CAAA;AAElC,eAAO,MAAM,kBAAkB,SACvB,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,gBAIgB,CAAA;AAElC,eAAO,MAAM,gBAAgB,SACrB,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,cAIQ,CAAA;AAE1B,eAAO,MAAM,iBAAiB,SACtB,OAAO,KACZ,IAAI,IAAI,QAAQ,CAAC;IAClB,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CACjC,CAIgC,CAAA;AAEjC,eAAO,MAAM,eAAe,SAAU,OAAO,KAAG,OAIjB,CAAA;AAE/B,eAAO,MAAM,eAAe,SACpB,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,uBAIuB,CAAA;AAEzC,eAAO,MAAM,gBAAgB,WAAY,OAAO,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAYtE,CAAA;AAkCD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC,mBAAmB,CAAA;IAChC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAC/B,CAAC,CAAA;AAEF,eAAO,MAAM,gBAAgB,SACrB,OAAO,KACZ,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAqBhC,CAAA;AAED,eAAO,MAAM,uBAAuB,WAC1B,OAAO,cACH,MAAM,KACjB,OACmE,CAAA;AAEtE,eAAO,MAAM,iBAAiB,SAAU,OAAO,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAUrE,CAAA;AAED,eAAO,MAAM,gBAAgB,SACrB,MAAM,CAAC,gBAAgB,KAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,CAKtB,CAAA;AAED,eAAO,MAAM,kBAAkB,aACnB,QAAQ,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,EAAE,MAAM,CAAC,WAAW,CAAA;CACxB,CAAC,KACD,MAAM,CAAC,MAAM,CAAC,MAAM,CAKtB,CAAA;AAED,eAAO,MAAM,eAAe,WAClB,aAAa,CAAC,WAAW,CAAC,KACjC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAShC,CAAA;AAED,eAAO,MAAM,gBAAgB,eACf,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,QACrC,MAAM,CAAC,mBAAmB,KAC/B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAGtB,CAAA;AAEH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC9B,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACpC,CAAC,CAAA;AAOF,eAAO,MAAM,mBAAmB,eAClB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,QACrC,OAAO,KACZ,MAAM,CAAC,MAAM,CAAC,YAAY,CA8BzB,CAAA;AAoBJ,eAAO,MAAM,qBAAqB,eACpB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,QACrC,OAAO,KACZ,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAUlC,CAAA;AAkGJ,eAAO,MAAM,0BAA0B,WAC7B,OAAO,cACH,MAAM,cACN,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,SAAS,KACtD,OA8BF,CAAA;AAED,eAAO,MAAM,qBAAqB,eACpB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,SAAS,QACjD,MAAM,CAAC,IAAI,KAChB,OAUF,CAAA;AAED,eAAO,MAAM,oBAAoB,SACzB,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,kBAIkB,CAAA;AAEpC,eAAO,MAAM,qBAAqB,SAC1B,OAAO,KACZ,IAAI,IAAI,MAAM,CAAC,mBAImB,CAAA;AAErC,eAAO,MAAM,SAAS,SAAU,OAAO,KAAG,IAAI,IAAI,MAAM,CAAC,OAIhC,CAAA;AAEzB,eAAO,MAAM,mBAAmB,SACxB,MAAM,CAAC,cAAc,KAC1B,MAAM,CAAC,aAAa,GAAG,SAGzB,CAAA"}
package/dist/index.js CHANGED
@@ -12114,7 +12114,8 @@ const foldkitNamespaceBySource = {
12114
12114
  "foldkit/schema": "Schema",
12115
12115
  "foldkit/struct": "Struct",
12116
12116
  "foldkit/submodel": "Submodel",
12117
- "foldkit/subscription": "Subscription"
12117
+ "foldkit/subscription": "Subscription",
12118
+ "foldkit/update": "Update"
12118
12119
  };
12119
12120
  const resolveFoldkitApiPath = (references, node) => flatMap$3(resolveImportedPath(references, node), (path) => {
12120
12121
  if (path.source === "foldkit") return some$1(path.members);
@@ -12998,7 +12999,7 @@ const noArrayIndexViewKeys = Rule_exports.define({
12998
12999
  //#endregion
12999
13000
  //#region src/rules/no-child-message-construction-in-root.ts
13000
13001
  const pascalIdentifierPattern = /^[A-Z][A-Za-z0-9]*$/;
13001
- const childMessageConstructionMessage = (calleeLabel) => `Do not construct the child Message \`${calleeLabel}(...)\` from a parent. Expose a child update capability that applies this fact, then invoke it with Update.foldChild or Update.foldChildStep. Child-owned views, Commands, and Subscriptions may construct their own Messages.`;
13002
+ const childMessageConstructionMessage = (calleeLabel) => `Do not construct the child Message \`${calleeLabel}(...)\` from a parent. Expose a child update capability that applies this fact, then invoke it with Update.foldChild, Update.foldChildAt, or Update.foldChildStep. Child-owned views, Commands, and Subscriptions may construct their own Messages.`;
13002
13003
  const moduleExtensionPattern = /\.(?:cjs|cts|js|jsx|mjs|mts|ts|tsx)$/;
13003
13004
  const moduleSegmentName = (segment) => segment.replace(moduleExtensionPattern, "");
13004
13005
  const messageModuleSegmentNames = /* @__PURE__ */ new Set([
@@ -13163,7 +13164,7 @@ const noChildMessageConstructionInRoot = Rule_exports.define({
13163
13164
  });
13164
13165
  //#endregion
13165
13166
  //#region src/rules/no-direct-submodel-state-update.ts
13166
- const directSubmodelStateUpdateMessage = (fieldName) => `Do not update the Submodel field \`${fieldName}\` directly from its parent. Expose a child-owned update capability, then apply it with Update.foldChild or Update.foldChildStep.`;
13167
+ const directSubmodelStateUpdateMessage = (fieldName) => `Do not update the Submodel field \`${fieldName}\` directly from its parent. Expose a child-owned update capability, then apply it with Update.foldChild, Update.foldChildAt, or Update.foldChildStep.`;
13167
13168
  const isNode$2 = (value) => typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
13168
13169
  const isArrowFunction = (value) => isNode$2(value) && value.type === "ArrowFunctionExpression";
13169
13170
  const isReturnStatement$3 = (value) => isNode$2(value) && value.type === "ReturnStatement";
@@ -13224,8 +13225,9 @@ const directReadField = (callback) => {
13224
13225
  const propertyValue = (object, name) => {
13225
13226
  for (const property of object.properties) if (property.type === "Property" && !property.computed && isIdentifier(property.key, name)) return property.value;
13226
13227
  };
13227
- const directWriteField = (callback, references) => {
13228
- const [modelParameter, nextChildParameter] = callback.params;
13228
+ const directWriteField = (callback, references, nextChildParameterIndex = 1) => {
13229
+ const [modelParameter, secondParameter, thirdParameter] = callback.params;
13230
+ const nextChildParameter = nextChildParameterIndex === 2 ? thirdParameter : secondParameter;
13229
13231
  if (!isIdentifier(modelParameter) || !isIdentifier(nextChildParameter)) return;
13230
13232
  const returned = expressionReturnedBy(callback);
13231
13233
  if (!isCallExpression$1(returned) || !isModifyFieldsCall$1(returned, references)) return;
@@ -13250,6 +13252,7 @@ const isModifyFieldsCall$1 = (node, references) => {
13250
13252
  const foldKind = (node, references) => {
13251
13253
  const foldKindForName = (helperName) => {
13252
13254
  if (helperName === "foldChild") return "Fold";
13255
+ if (helperName === "foldChildAt") return "Keyed";
13253
13256
  if (helperName === "foldChildStep") return "Step";
13254
13257
  };
13255
13258
  if (references === void 0) return getOrUndefined(flatMap$3(staticMemberPath(node.callee), (path) => {
@@ -13307,12 +13310,14 @@ const foldDefinitions = (program, scopes, references) => {
13307
13310
  if (kind === void 0) continue;
13308
13311
  const [configuration] = declarator.init.arguments;
13309
13312
  if (!isObjectExpression(configuration)) continue;
13310
- const read = callbackValue$1(propertyValue(configuration, "read"), callbacks);
13311
- const write = callbackValue$1(propertyValue(configuration, "write"), callbacks);
13313
+ const readPropertyName = kind === "Keyed" ? "readAt" : "read";
13314
+ const writePropertyName = kind === "Keyed" ? "writeAt" : "write";
13315
+ const read = callbackValue$1(propertyValue(configuration, readPropertyName), callbacks);
13316
+ const write = callbackValue$1(propertyValue(configuration, writePropertyName), callbacks);
13312
13317
  if (read === void 0 || write === void 0) continue;
13313
13318
  writeCallbacks.add(write);
13314
13319
  const readField = directReadField(read);
13315
- const writeField = directWriteField(write, references);
13320
+ const writeField = directWriteField(write, references, kind === "Keyed" ? 2 : 1);
13316
13321
  if (readField === void 0 || readField !== writeField) continue;
13317
13322
  const definition = {
13318
13323
  childField: readField,
@@ -13348,7 +13353,7 @@ const childFieldsForCombine = (node, definitions, references) => {
13348
13353
  }
13349
13354
  if (!isCallExpression$1(step)) continue;
13350
13355
  const definition = foldDefinitionFor(step.callee, definitions, references);
13351
- if (definition?.kind === "Fold") childFields.add(definition.childField);
13356
+ if (definition?.kind === "Fold" || definition?.kind === "Keyed") childFields.add(definition.childField);
13352
13357
  }
13353
13358
  return childFields;
13354
13359
  };
@@ -13419,9 +13424,11 @@ const foldEvidence = (program, scopes, references) => {
13419
13424
  }
13420
13425
  const directDefinition = foldDefinitionFor(node.callee, definitions, references);
13421
13426
  const dataLastDefinition = isCallExpression$1(node.callee) ? foldDefinitionFor(node.callee.callee, definitions, references) : void 0;
13422
- if (directDefinition === void 0 && (dataLastDefinition === void 0 || dataLastDefinition.kind !== "Fold")) return;
13423
- const [firstArgument, secondArgument] = node.arguments;
13427
+ if (directDefinition === void 0 && dataLastDefinition === void 0) return;
13428
+ const [firstArgument, secondArgument, thirdArgument] = node.arguments;
13424
13429
  if (directDefinition?.kind === "Fold" && secondArgument === void 0) return;
13430
+ if (directDefinition?.kind === "Keyed" && thirdArgument === void 0) return;
13431
+ if (dataLastDefinition?.kind === "Step") return;
13425
13432
  const definition = directDefinition ?? dataLastDefinition;
13426
13433
  const parentModel = firstArgument;
13427
13434
  if (!isIdentifierReference(parentModel) || definition === void 0) return;
@@ -13996,7 +14003,19 @@ const directlyReturnsUndefined = (references, mapper) => {
13996
14003
  const [firstStatement, secondStatement] = mapper.body.body;
13997
14004
  return firstStatement?.type === "ReturnStatement" && secondStatement === void 0 && isUnshadowedUndefined(references, firstStatement.argument);
13998
14005
  };
13999
- const isEmptyMapperProperty = (references, property) => property.kind === "init" && contains$1(staticPropertyName(property), TO_PARENT_OUT_MESSAGE_PROPERTY) && isMapperFunction(property.value) && directlyReturnsUndefined(references, property.value);
14006
+ const directlyReturnedMapper = (mapper) => {
14007
+ if (mapper.body === null) return;
14008
+ if (mapper.body.type !== "BlockStatement") return isMapperFunction(mapper.body) ? mapper.body : void 0;
14009
+ const [firstStatement, secondStatement] = mapper.body.body;
14010
+ if (firstStatement?.type !== "ReturnStatement" || secondStatement !== void 0 || !isMapperFunction(firstStatement.argument)) return;
14011
+ return firstStatement.argument;
14012
+ };
14013
+ const forwardsNothing = (references, mapper) => {
14014
+ if (directlyReturnsUndefined(references, mapper)) return true;
14015
+ const returnedMapper = directlyReturnedMapper(mapper);
14016
+ return returnedMapper !== void 0 && directlyReturnsUndefined(references, returnedMapper);
14017
+ };
14018
+ const isEmptyMapperProperty = (references, property) => property.kind === "init" && contains$1(staticPropertyName(property), TO_PARENT_OUT_MESSAGE_PROPERTY) && isMapperFunction(property.value) && forwardsNothing(references, property.value);
14000
14019
  const removalRange = (sourceText, object, property, index) => {
14001
14020
  const maybePrevious = get$1(object.properties, index - 1);
14002
14021
  if (isSome(maybePrevious)) return [maybePrevious.value.end, property.end];
@@ -14008,18 +14027,19 @@ const removalRange = (sourceText, object, property, index) => {
14008
14027
  if (isNone(maybeMatchedText)) return property.range;
14009
14028
  return [property.start, property.end + maybeMatchedText.value.length];
14010
14029
  };
14011
- const emptyMapperMessage = "Omit toParentOutMessage. This mapper directly returns undefined, so it forwards nothing to the parent.";
14030
+ const emptyMapperMessage = "Omit toParentOutMessage. Its inline mapper returns undefined for every child OutMessage, so it forwards nothing to the parent.";
14012
14031
  /**
14013
14032
  * Flags an inline `toParentOutMessage` mapper that directly returns
14014
- * `undefined`. That mapper forwards nothing to the parent, so the property
14015
- * should be omitted. This syntax-only rule does not inspect async functions,
14016
- * generators, getters, setters, or mappers referenced by name.
14033
+ * `undefined`, including the mapper returned by a keyed mapper factory. That
14034
+ * mapper forwards nothing to the parent, so the property should be omitted.
14035
+ * This syntax-only rule does not inspect async functions, generators, getters,
14036
+ * setters, or mappers referenced by name.
14017
14037
  */
14018
14038
  const noEmptyToParentOutMessage = Rule_exports.define({
14019
14039
  name: "no-empty-to-parent-out-message",
14020
14040
  meta: Rule_exports.meta({
14021
14041
  type: "suggestion",
14022
- description: "Omit an inline toParentOutMessage mapper that directly returns undefined.",
14042
+ description: "Omit an inline toParentOutMessage mapper that returns undefined for every child OutMessage.",
14023
14043
  fixable: "code"
14024
14044
  }),
14025
14045
  create: function* () {
@@ -15121,7 +15141,7 @@ const referencedFunction = (node, references) => {
15121
15141
  return isVariableDeclarator$1(definition.node) && isFunctionNode(definition.node.init) ? some$1(definition.node.init) : none();
15122
15142
  }));
15123
15143
  };
15124
- const diagnosticMessage = (operatorName) => `\`preventDefault()\` inside a \`Stream.${operatorName}\` callback does not reliably run inside the browser's event dispatch. For a DOM-event Stream, the default action may already have happened by the time the callback runs. Cancel the event inside the listener with \`Subscription.fromEventFilterMapPreventDefault\`, which calls \`preventDefault()\` for every handled event before the native listener returns. If this callback does not handle a DOM event, suppress this rule with a disable comment.`;
15144
+ const diagnosticMessage = (operatorName) => `\`preventDefault()\` inside a \`Stream.${operatorName}\` callback does not reliably run inside the browser's event dispatch. For a DOM-event Stream, the default action may already have happened by the time the callback runs. Cancel the event inside the listener with \`Dom.streamFromEventFilterMapPreventDefault\`, which calls \`preventDefault()\` for every handled event before the native listener returns. If this callback does not handle a DOM event, suppress this rule with a disable comment.`;
15125
15145
  /**
15126
15146
  * Flags `event.preventDefault()` inside callbacks passed to Stream operators
15127
15147
  * (`Stream.map`, `Stream.mapEffect`, `Stream.filterMap`,
@@ -15129,7 +15149,7 @@ const diagnosticMessage = (operatorName) => `\`preventDefault()\` inside a \`Str
15129
15149
  * `Stream.tap`).
15130
15150
  * Those callbacks do not reliably run inside the browser's event dispatch.
15131
15151
  * For a DOM-event Stream, cancellation belongs inside the native listener,
15132
- * which is where `Subscription.fromEventFilterMapPreventDefault` runs its
15152
+ * which is where `Dom.streamFromEventFilterMapPreventDefault` runs its
15133
15153
  * mapper.
15134
15154
  */
15135
15155
  const noPreventDefaultInStreamOperator = Rule_exports.define({
@@ -15770,14 +15790,14 @@ const isFoldkitModifyFieldsCall = (node, references) => {
15770
15790
  return exists(staticMemberPath(node.callee), (path) => path.root.name === "modifyFields" && isReadonlyArrayEmpty(path.members) || path.root.name === "Struct" && sameNames(path.members, ["modifyFields"]));
15771
15791
  };
15772
15792
  const isFoldCall = (node, references) => {
15773
- const isFoldPath = (path) => sameNames(path, ["Update", "foldChild"]) || sameNames(path, ["Update", "foldChildStep"]);
15793
+ const isFoldPath = (path) => sameNames(path, ["Update", "foldChild"]) || sameNames(path, ["Update", "foldChildAt"]) || sameNames(path, ["Update", "foldChildStep"]);
15774
15794
  if (references !== void 0) return exists(resolveFoldkitApiPath(references, node.callee), isFoldPath);
15775
15795
  return exists(staticMemberPath(node.callee), (path) => isFoldPath([path.root.name, ...path.members]));
15776
15796
  };
15777
15797
  const isInsideFoldWrite = (node, references) => {
15778
15798
  let ancestor = node.parent;
15779
15799
  while (ancestor !== null && ancestor !== void 0) {
15780
- if (isObjectProperty(ancestor) && contains$1(staticPropertyName(ancestor), "write") && isObjectExpression(ancestor.parent) && isCallExpression$1(ancestor.parent.parent) && isFoldCall(ancestor.parent.parent, references)) return true;
15800
+ if (isObjectProperty(ancestor) && exists(staticPropertyName(ancestor), (propertyName) => propertyName === "write" || propertyName === "writeAt") && isObjectExpression(ancestor.parent) && isCallExpression$1(ancestor.parent.parent) && isFoldCall(ancestor.parent.parent, references)) return true;
15781
15801
  ancestor = ancestor.parent;
15782
15802
  }
15783
15803
  return false;
@@ -15816,8 +15836,9 @@ const modelFieldNames = (functionNode) => {
15816
15836
  });
15817
15837
  return fieldNames;
15818
15838
  };
15819
- const modifyFieldsFieldNames = (functionNode, references) => {
15820
- const [parentModel, nextChild] = functionNode.params;
15839
+ const modifyFieldsFieldNames = (functionNode, references, nextChildParameterIndex = 1) => {
15840
+ const [parentModel, secondParameter, thirdParameter] = functionNode.params;
15841
+ const nextChild = nextChildParameterIndex === 2 ? thirdParameter : secondParameter;
15821
15842
  if (!isIdentifier(parentModel) || !isIdentifier(nextChild)) return /* @__PURE__ */ new Set();
15822
15843
  const fieldNames = /* @__PURE__ */ new Set();
15823
15844
  walk(functionNode.body, (node) => {
@@ -15861,12 +15882,12 @@ const foldChildFieldsByNamespace = (program, references) => {
15861
15882
  if (contains$1(staticPropertyName(property), "update")) pipe(staticMemberPath(property.value), filter$2((path) => length(path.members) === 1), map$5((path) => {
15862
15883
  namespace = path.root.name;
15863
15884
  }));
15864
- else if (contains$1(staticPropertyName(property), "read")) {
15885
+ else if (exists(staticPropertyName(property), (propertyName) => propertyName === "read" || propertyName === "readAt")) {
15865
15886
  const callback = callbackValue(property.value, callbacks);
15866
15887
  if (callback !== void 0) readFields = modelFieldNames(callback);
15867
- } else if (contains$1(staticPropertyName(property), "write")) {
15888
+ } else if (exists(staticPropertyName(property), (propertyName) => propertyName === "write" || propertyName === "writeAt")) {
15868
15889
  const callback = callbackValue(property.value, callbacks);
15869
- if (callback !== void 0) writeFields = modifyFieldsFieldNames(callback, references);
15890
+ if (callback !== void 0) writeFields = modifyFieldsFieldNames(callback, references, contains$1(staticPropertyName(property), "writeAt") ? 2 : 1);
15870
15891
  }
15871
15892
  }
15872
15893
  if (namespace === void 0 || readFields === void 0 || writeFields === void 0) return;
@@ -15912,11 +15933,12 @@ const sameBinding = (a, b, references) => {
15912
15933
  const maybeB = resolvedVariable(references, b);
15913
15934
  return isSome(maybeA) && isSome(maybeB) ? maybeA.value === maybeB.value : a.name === b.name;
15914
15935
  };
15915
- const manualChildResultMessage = (childFieldName, helperLabel, resultName) => `The parent writes \`${resultName}.model\` into \`${childFieldName}\` after calling \`${helperLabel}\`. A child Return can include Commands or an OutMessage that this copy ignores. Use Update.foldChild or Update.foldChildStep.`;
15936
+ const manualChildResultMessage = (childFieldName, helperLabel, resultName) => `The parent writes \`${resultName}.model\` into \`${childFieldName}\` after calling \`${helperLabel}\`. A child Return can include Commands or an OutMessage that this copy ignores. Use Update.foldChild, Update.foldChildAt, or Update.foldChildStep.`;
15916
15937
  /** Flags a parent that copies a namespaced child helper or update Return's Model
15917
- * into the matching modifyFields field. It requires a matching Update.foldChild or
15918
- * Update.foldChildStep reference in the file, and leaves ordinary helpers,
15919
- * direct imports, aliases, init assembly, and Model-only reflect helpers alone. */
15938
+ * into the matching modifyFields field. It requires a matching
15939
+ * Update.foldChild, Update.foldChildAt, or Update.foldChildStep reference in
15940
+ * the file, and leaves ordinary helpers, direct imports, aliases, init
15941
+ * assembly, keyed collection writes, and Model-only reflect helpers alone. */
15920
15942
  const requireFoldForChildUpdateResult = Rule_exports.define({
15921
15943
  name: "require-fold-for-child-update-result",
15922
15944
  meta: Rule_exports.meta({
@@ -1 +1 @@
1
- {"version":3,"file":"no-direct-submodel-state-update.d.ts","sourceRoot":"","sources":["../../src/rules/no-direct-submodel-state-update.ts"],"names":[],"mappings":"AA0yBA,yFAAyF;AACzF,eAAO,MAAM,2BAA2B,oCA+DtC,CAAA"}
1
+ {"version":3,"file":"no-direct-submodel-state-update.d.ts","sourceRoot":"","sources":["../../src/rules/no-direct-submodel-state-update.ts"],"names":[],"mappings":"AAyzBA,yFAAyF;AACzF,eAAO,MAAM,2BAA2B,oCA+DtC,CAAA"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Flags an inline `toParentOutMessage` mapper that directly returns
3
- * `undefined`. That mapper forwards nothing to the parent, so the property
4
- * should be omitted. This syntax-only rule does not inspect async functions,
5
- * generators, getters, setters, or mappers referenced by name.
3
+ * `undefined`, including the mapper returned by a keyed mapper factory. That
4
+ * mapper forwards nothing to the parent, so the property should be omitted.
5
+ * This syntax-only rule does not inspect async functions, generators, getters,
6
+ * setters, or mappers referenced by name.
6
7
  */
7
8
  export declare const noEmptyToParentOutMessage: import("effect-oxlint").CreateRule;
8
9
  //# sourceMappingURL=no-empty-to-parent-out-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-empty-to-parent-out-message.d.ts","sourceRoot":"","sources":["../../src/rules/no-empty-to-parent-out-message.ts"],"names":[],"mappings":"AAgHA;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,oCAgFpC,CAAA"}
1
+ {"version":3,"file":"no-empty-to-parent-out-message.d.ts","sourceRoot":"","sources":["../../src/rules/no-empty-to-parent-out-message.ts"],"names":[],"mappings":"AAqJA;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,oCAgFpC,CAAA"}
@@ -5,7 +5,7 @@
5
5
  * `Stream.tap`).
6
6
  * Those callbacks do not reliably run inside the browser's event dispatch.
7
7
  * For a DOM-event Stream, cancellation belongs inside the native listener,
8
- * which is where `Subscription.fromEventFilterMapPreventDefault` runs its
8
+ * which is where `Dom.streamFromEventFilterMapPreventDefault` runs its
9
9
  * mapper.
10
10
  */
11
11
  export declare const noPreventDefaultInStreamOperator: import("effect-oxlint").CreateRule;
@@ -1,6 +1,7 @@
1
1
  /** Flags a parent that copies a namespaced child helper or update Return's Model
2
- * into the matching modifyFields field. It requires a matching Update.foldChild or
3
- * Update.foldChildStep reference in the file, and leaves ordinary helpers,
4
- * direct imports, aliases, init assembly, and Model-only reflect helpers alone. */
2
+ * into the matching modifyFields field. It requires a matching
3
+ * Update.foldChild, Update.foldChildAt, or Update.foldChildStep reference in
4
+ * the file, and leaves ordinary helpers, direct imports, aliases, init
5
+ * assembly, keyed collection writes, and Model-only reflect helpers alone. */
5
6
  export declare const requireFoldForChildUpdateResult: import("effect-oxlint").CreateRule;
6
7
  //# sourceMappingURL=require-fold-for-child-update-result.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"require-fold-for-child-update-result.d.ts","sourceRoot":"","sources":["../../src/rules/require-fold-for-child-update-result.ts"],"names":[],"mappings":"AAocA;;;oFAGoF;AACpF,eAAO,MAAM,+BAA+B,oCAiJ1C,CAAA"}
1
+ {"version":3,"file":"require-fold-for-child-update-result.d.ts","sourceRoot":"","sources":["../../src/rules/require-fold-for-child-update-result.ts"],"names":[],"mappings":"AA0dA;;;;+EAI+E;AAC/E,eAAO,MAAM,+BAA+B,oCAiJ1C,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldkit/oxlint-plugin",
3
- "version": "0.15.2-canary.085b787da0a5",
3
+ "version": "0.15.2-canary.3b49f516b024",
4
4
  "description": "Oxlint rules for Foldkit applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",