atom.io 0.21.0 → 0.22.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.
Files changed (99) hide show
  1. package/data/dist/index.cjs +139 -66
  2. package/data/dist/index.d.ts +6 -0
  3. package/data/dist/index.js +3 -3
  4. package/data/src/join.ts +135 -56
  5. package/data/src/struct-family.ts +2 -2
  6. package/dist/{chunk-RT43TVKP.js → chunk-GVHKIJ3G.js} +1 -1
  7. package/dist/{chunk-KGZGBCYS.js → chunk-JA4V7TJY.js} +135 -62
  8. package/dist/index.cjs +2 -7
  9. package/dist/index.d.ts +29 -14
  10. package/dist/index.js +4 -8
  11. package/ephemeral/dist/index.cjs +11 -0
  12. package/ephemeral/dist/index.js +9 -0
  13. package/ephemeral/package.json +16 -0
  14. package/ephemeral/src/index.ts +1 -0
  15. package/eslint-plugin/dist/index.cjs +156 -1
  16. package/eslint-plugin/dist/index.js +156 -1
  17. package/eslint-plugin/src/rules/index.ts +1 -0
  18. package/eslint-plugin/src/rules/lifespan.ts +204 -0
  19. package/eslint-plugin/src/rules/synchronous-selector-dependencies.ts +1 -65
  20. package/eslint-plugin/src/walk.ts +73 -0
  21. package/immortal/dist/index.cjs +100 -0
  22. package/immortal/dist/index.js +97 -0
  23. package/immortal/package.json +16 -0
  24. package/immortal/src/index.ts +2 -0
  25. package/immortal/src/molecule.ts +134 -0
  26. package/immortal/src/seek-state.ts +60 -0
  27. package/internal/dist/index.cjs +211 -194
  28. package/internal/dist/index.d.ts +30 -14
  29. package/internal/dist/index.js +210 -194
  30. package/internal/src/atom/dispose-atom.ts +4 -1
  31. package/internal/src/families/create-readonly-selector-family.ts +9 -9
  32. package/internal/src/families/create-regular-atom-family.ts +15 -20
  33. package/internal/src/families/create-writable-selector-family.ts +6 -7
  34. package/internal/src/families/find-in-store.ts +11 -5
  35. package/internal/src/families/index.ts +2 -0
  36. package/internal/src/families/init-family-member.ts +91 -0
  37. package/internal/src/families/seek-in-store.ts +106 -0
  38. package/internal/src/future.ts +6 -20
  39. package/internal/src/get-state/get-from-store.ts +2 -3
  40. package/internal/src/mutable/create-mutable-atom-family.ts +17 -23
  41. package/internal/src/mutable/create-mutable-atom.ts +3 -1
  42. package/internal/src/mutable/get-json-family.ts +2 -2
  43. package/internal/src/mutable/get-json-token.ts +27 -12
  44. package/internal/src/mutable/tracker-family.ts +14 -12
  45. package/internal/src/mutable/tracker.ts +2 -24
  46. package/internal/src/not-found-error.ts +11 -3
  47. package/internal/src/operation.ts +0 -1
  48. package/internal/src/selector/create-readonly-selector.ts +2 -2
  49. package/internal/src/selector/create-writable-selector.ts +2 -2
  50. package/internal/src/selector/dispose-selector.ts +40 -23
  51. package/internal/src/selector/register-selector.ts +8 -5
  52. package/internal/src/set-state/set-into-store.ts +2 -2
  53. package/internal/src/store/index.ts +0 -1
  54. package/internal/src/store/store.ts +18 -5
  55. package/internal/src/subscribe/recall-state.ts +3 -3
  56. package/internal/src/subscribe/subscribe-to-state.ts +18 -5
  57. package/internal/src/transaction/build-transaction.ts +7 -2
  58. package/introspection/dist/index.cjs +39 -65
  59. package/introspection/dist/index.js +39 -65
  60. package/introspection/src/attach-atom-index.ts +38 -48
  61. package/introspection/src/attach-introspection-states.ts +0 -1
  62. package/introspection/src/attach-selector-index.ts +45 -50
  63. package/introspection/src/attach-timeline-family.ts +2 -17
  64. package/json/dist/index.cjs +38 -4
  65. package/json/dist/index.js +40 -6
  66. package/json/src/select-json-family.ts +46 -7
  67. package/package.json +31 -11
  68. package/react/dist/index.cjs +1 -1
  69. package/react/dist/index.js +1 -1
  70. package/react/src/use-json.ts +1 -1
  71. package/react-devtools/dist/index.cjs +11 -10
  72. package/react-devtools/dist/index.js +2 -1
  73. package/react-devtools/src/StateIndex.tsx +2 -1
  74. package/react-devtools/src/TimelineIndex.tsx +2 -1
  75. package/react-devtools/src/TransactionIndex.tsx +7 -7
  76. package/realtime-client/dist/index.cjs +3 -3
  77. package/realtime-client/dist/index.js +3 -3
  78. package/realtime-client/src/pull-mutable-atom-family-member.ts +1 -1
  79. package/realtime-client/src/pull-mutable-atom.ts +1 -1
  80. package/realtime-client/src/sync-continuity.ts +1 -2
  81. package/realtime-react/dist/index.cjs +1 -1
  82. package/realtime-react/dist/index.js +1 -1
  83. package/realtime-server/dist/index.cjs +18 -17
  84. package/realtime-server/dist/index.js +7 -6
  85. package/realtime-server/src/realtime-continuity-synchronizer.ts +5 -3
  86. package/realtime-server/src/realtime-mutable-family-provider.ts +2 -1
  87. package/realtime-server/src/realtime-mutable-provider.ts +1 -1
  88. package/realtime-testing/dist/index.cjs +6 -2
  89. package/realtime-testing/dist/index.js +8 -5
  90. package/realtime-testing/src/setup-realtime-test.tsx +5 -2
  91. package/src/atom.ts +10 -4
  92. package/src/index.ts +1 -2
  93. package/src/selector.ts +10 -4
  94. package/src/silo.ts +3 -3
  95. package/src/transaction.ts +5 -2
  96. package/src/validators.ts +0 -6
  97. package/internal/src/store/withdraw-new-family-member.ts +0 -69
  98. /package/{src → ephemeral/src}/find-state.ts +0 -0
  99. /package/src/{dispose.ts → dispose-state.ts} +0 -0
@@ -14,6 +14,7 @@ var __export = (target, all) => {
14
14
  var rules_exports = {};
15
15
  __export(rules_exports, {
16
16
  explicitStateTypes: () => explicitStateTypes,
17
+ lifespan: () => lifespan,
17
18
  synchronousSelectorDependencies: () => synchronousSelectorDependencies
18
19
  });
19
20
  var createRule = utils.ESLintUtils.RuleCreator(
@@ -66,7 +67,7 @@ var explicitStateTypes = createRule({
66
67
  }
67
68
  });
68
69
 
69
- // eslint-plugin/src/rules/synchronous-selector-dependencies.ts
70
+ // eslint-plugin/src/walk.ts
70
71
  function walk(node, callback, depth = 0) {
71
72
  callback(node, depth);
72
73
  switch (node.type) {
@@ -125,8 +126,162 @@ function walk(node, callback, depth = 0) {
125
126
  walk(node.object, callback, depth);
126
127
  walk(node.property, callback, depth);
127
128
  break;
129
+ case `CallExpression`:
130
+ walk(node.callee, callback, depth);
131
+ for (const argument of node.arguments) {
132
+ walk(argument, callback, depth);
133
+ }
134
+ break;
128
135
  }
129
136
  }
137
+
138
+ // eslint-plugin/src/rules/lifespan.ts
139
+ var lifespan = {
140
+ meta: {
141
+ type: `problem`,
142
+ docs: {
143
+ description: `atom.io provides tools for short-lived (ephemeral) and long-lived (immortal) stores. This rule allows you to guard against unsafe usage of tools for the other type of store.`,
144
+ category: `Possible Errors`,
145
+ recommended: false,
146
+ url: ``
147
+ // URL to documentation page for this rule
148
+ },
149
+ schema: [
150
+ {
151
+ type: `string`,
152
+ enum: [`ephemeral`, `immortal`],
153
+ default: `ephemeral`
154
+ }
155
+ ]
156
+ },
157
+ create(context) {
158
+ var _a;
159
+ const storeLifespan = (_a = context.options[0]) != null ? _a : `ephemeral`;
160
+ return {
161
+ ImportDeclaration(node) {
162
+ const importSource = node.source.value;
163
+ if (!importSource.startsWith(`atom.io/`)) {
164
+ return;
165
+ }
166
+ const [_, subPackageName] = importSource.split(`/`);
167
+ if (storeLifespan === `immortal` && subPackageName === `ephemeral`) {
168
+ context.report({
169
+ node,
170
+ message: `do not import from "${importSource}" in an ${storeLifespan} store`
171
+ });
172
+ }
173
+ },
174
+ CallExpression(node) {
175
+ if (storeLifespan === `ephemeral`) {
176
+ return;
177
+ }
178
+ const functionCallee = node.callee.type === `Identifier` ? node.callee : void 0;
179
+ const methodCallee = node.callee.type === `MemberExpression` && node.callee.property.type === `Identifier` ? node.callee.property : void 0;
180
+ const callee = functionCallee != null ? functionCallee : methodCallee;
181
+ if (callee === void 0) {
182
+ return;
183
+ }
184
+ if (callee.name === `findState`) {
185
+ context.report({
186
+ node,
187
+ message: `do not use findState in an ${storeLifespan} store`
188
+ });
189
+ }
190
+ const storeProcedures = [];
191
+ if (callee.name === `selector` || callee.name === `selectorFamily` || callee.name === `transaction`) {
192
+ if (node.arguments[0].type === `ObjectExpression`) {
193
+ const argProperties = node.arguments[0].properties;
194
+ switch (callee.name) {
195
+ case `selector`:
196
+ case `selectorFamily`:
197
+ {
198
+ const getAndSetProps = argProperties.filter(
199
+ (prop) => {
200
+ return `key` in prop && `name` in prop.key && (prop.key.name === `get` || prop.key.name === `set`);
201
+ }
202
+ );
203
+ switch (callee.name) {
204
+ case `selector`:
205
+ {
206
+ for (const prop of getAndSetProps) {
207
+ if (prop.value.type === `FunctionExpression` || prop.value.type === `ArrowFunctionExpression`) {
208
+ console.log(prop.value);
209
+ storeProcedures.push(prop.value);
210
+ }
211
+ }
212
+ }
213
+ break;
214
+ case `selectorFamily`:
215
+ {
216
+ for (const prop of getAndSetProps) {
217
+ const { value } = prop;
218
+ if (value.type === `FunctionExpression` || value.type === `ArrowFunctionExpression`) {
219
+ if (value.body.type === `BlockStatement`) {
220
+ for (const statement of value.body.body) {
221
+ if (statement.type === `ReturnStatement` && statement.argument && (statement.argument.type === `FunctionExpression` || statement.argument.type === `ArrowFunctionExpression`)) {
222
+ storeProcedures.push(statement.argument);
223
+ }
224
+ }
225
+ } else if (value.body.type === `FunctionExpression` || value.body.type === `ArrowFunctionExpression`) {
226
+ storeProcedures.push(value.body);
227
+ }
228
+ }
229
+ }
230
+ }
231
+ break;
232
+ }
233
+ }
234
+ break;
235
+ case `transaction`:
236
+ {
237
+ const doProp = argProperties.find(
238
+ (prop) => {
239
+ return `key` in prop && `name` in prop.key && prop.key.name === `do`;
240
+ }
241
+ );
242
+ if (doProp) {
243
+ if (doProp.value.type === `FunctionExpression` || doProp.value.type === `ArrowFunctionExpression`) {
244
+ storeProcedures.push(doProp.value);
245
+ }
246
+ }
247
+ }
248
+ break;
249
+ }
250
+ }
251
+ }
252
+ for (const storeProcedure of storeProcedures) {
253
+ const transactorsParam = storeProcedure.params[0];
254
+ const nonDestructuredTransactorsName = transactorsParam && `name` in transactorsParam ? transactorsParam.name : void 0;
255
+ walk(storeProcedure.body, (n) => {
256
+ if (n.type === `CallExpression`) {
257
+ let willReport = false;
258
+ switch (n.callee.type) {
259
+ case `MemberExpression`:
260
+ if (n.callee.object.type === `Identifier` && n.callee.object.name === nonDestructuredTransactorsName && n.callee.property.type === `Identifier` && n.callee.property.name === `find`) {
261
+ willReport = true;
262
+ }
263
+ break;
264
+ case `Identifier`:
265
+ if (n.callee.name === `find`) {
266
+ willReport = true;
267
+ }
268
+ break;
269
+ }
270
+ if (willReport) {
271
+ context.report({
272
+ node: n,
273
+ message: `Using find in a transactor is not allowed in an immortal store.`
274
+ });
275
+ }
276
+ }
277
+ });
278
+ }
279
+ }
280
+ };
281
+ }
282
+ };
283
+
284
+ // eslint-plugin/src/rules/synchronous-selector-dependencies.ts
130
285
  var synchronousSelectorDependencies = {
131
286
  meta: {
132
287
  type: `problem`,
@@ -5,6 +5,7 @@ import { ESLintUtils } from '@typescript-eslint/utils';
5
5
  var rules_exports = {};
6
6
  __export(rules_exports, {
7
7
  explicitStateTypes: () => explicitStateTypes,
8
+ lifespan: () => lifespan,
8
9
  synchronousSelectorDependencies: () => synchronousSelectorDependencies
9
10
  });
10
11
  var createRule = ESLintUtils.RuleCreator(
@@ -57,7 +58,7 @@ var explicitStateTypes = createRule({
57
58
  }
58
59
  });
59
60
 
60
- // eslint-plugin/src/rules/synchronous-selector-dependencies.ts
61
+ // eslint-plugin/src/walk.ts
61
62
  function walk(node, callback, depth = 0) {
62
63
  callback(node, depth);
63
64
  switch (node.type) {
@@ -116,8 +117,162 @@ function walk(node, callback, depth = 0) {
116
117
  walk(node.object, callback, depth);
117
118
  walk(node.property, callback, depth);
118
119
  break;
120
+ case `CallExpression`:
121
+ walk(node.callee, callback, depth);
122
+ for (const argument of node.arguments) {
123
+ walk(argument, callback, depth);
124
+ }
125
+ break;
119
126
  }
120
127
  }
128
+
129
+ // eslint-plugin/src/rules/lifespan.ts
130
+ var lifespan = {
131
+ meta: {
132
+ type: `problem`,
133
+ docs: {
134
+ description: `atom.io provides tools for short-lived (ephemeral) and long-lived (immortal) stores. This rule allows you to guard against unsafe usage of tools for the other type of store.`,
135
+ category: `Possible Errors`,
136
+ recommended: false,
137
+ url: ``
138
+ // URL to documentation page for this rule
139
+ },
140
+ schema: [
141
+ {
142
+ type: `string`,
143
+ enum: [`ephemeral`, `immortal`],
144
+ default: `ephemeral`
145
+ }
146
+ ]
147
+ },
148
+ create(context) {
149
+ var _a;
150
+ const storeLifespan = (_a = context.options[0]) != null ? _a : `ephemeral`;
151
+ return {
152
+ ImportDeclaration(node) {
153
+ const importSource = node.source.value;
154
+ if (!importSource.startsWith(`atom.io/`)) {
155
+ return;
156
+ }
157
+ const [_, subPackageName] = importSource.split(`/`);
158
+ if (storeLifespan === `immortal` && subPackageName === `ephemeral`) {
159
+ context.report({
160
+ node,
161
+ message: `do not import from "${importSource}" in an ${storeLifespan} store`
162
+ });
163
+ }
164
+ },
165
+ CallExpression(node) {
166
+ if (storeLifespan === `ephemeral`) {
167
+ return;
168
+ }
169
+ const functionCallee = node.callee.type === `Identifier` ? node.callee : void 0;
170
+ const methodCallee = node.callee.type === `MemberExpression` && node.callee.property.type === `Identifier` ? node.callee.property : void 0;
171
+ const callee = functionCallee != null ? functionCallee : methodCallee;
172
+ if (callee === void 0) {
173
+ return;
174
+ }
175
+ if (callee.name === `findState`) {
176
+ context.report({
177
+ node,
178
+ message: `do not use findState in an ${storeLifespan} store`
179
+ });
180
+ }
181
+ const storeProcedures = [];
182
+ if (callee.name === `selector` || callee.name === `selectorFamily` || callee.name === `transaction`) {
183
+ if (node.arguments[0].type === `ObjectExpression`) {
184
+ const argProperties = node.arguments[0].properties;
185
+ switch (callee.name) {
186
+ case `selector`:
187
+ case `selectorFamily`:
188
+ {
189
+ const getAndSetProps = argProperties.filter(
190
+ (prop) => {
191
+ return `key` in prop && `name` in prop.key && (prop.key.name === `get` || prop.key.name === `set`);
192
+ }
193
+ );
194
+ switch (callee.name) {
195
+ case `selector`:
196
+ {
197
+ for (const prop of getAndSetProps) {
198
+ if (prop.value.type === `FunctionExpression` || prop.value.type === `ArrowFunctionExpression`) {
199
+ console.log(prop.value);
200
+ storeProcedures.push(prop.value);
201
+ }
202
+ }
203
+ }
204
+ break;
205
+ case `selectorFamily`:
206
+ {
207
+ for (const prop of getAndSetProps) {
208
+ const { value } = prop;
209
+ if (value.type === `FunctionExpression` || value.type === `ArrowFunctionExpression`) {
210
+ if (value.body.type === `BlockStatement`) {
211
+ for (const statement of value.body.body) {
212
+ if (statement.type === `ReturnStatement` && statement.argument && (statement.argument.type === `FunctionExpression` || statement.argument.type === `ArrowFunctionExpression`)) {
213
+ storeProcedures.push(statement.argument);
214
+ }
215
+ }
216
+ } else if (value.body.type === `FunctionExpression` || value.body.type === `ArrowFunctionExpression`) {
217
+ storeProcedures.push(value.body);
218
+ }
219
+ }
220
+ }
221
+ }
222
+ break;
223
+ }
224
+ }
225
+ break;
226
+ case `transaction`:
227
+ {
228
+ const doProp = argProperties.find(
229
+ (prop) => {
230
+ return `key` in prop && `name` in prop.key && prop.key.name === `do`;
231
+ }
232
+ );
233
+ if (doProp) {
234
+ if (doProp.value.type === `FunctionExpression` || doProp.value.type === `ArrowFunctionExpression`) {
235
+ storeProcedures.push(doProp.value);
236
+ }
237
+ }
238
+ }
239
+ break;
240
+ }
241
+ }
242
+ }
243
+ for (const storeProcedure of storeProcedures) {
244
+ const transactorsParam = storeProcedure.params[0];
245
+ const nonDestructuredTransactorsName = transactorsParam && `name` in transactorsParam ? transactorsParam.name : void 0;
246
+ walk(storeProcedure.body, (n) => {
247
+ if (n.type === `CallExpression`) {
248
+ let willReport = false;
249
+ switch (n.callee.type) {
250
+ case `MemberExpression`:
251
+ if (n.callee.object.type === `Identifier` && n.callee.object.name === nonDestructuredTransactorsName && n.callee.property.type === `Identifier` && n.callee.property.name === `find`) {
252
+ willReport = true;
253
+ }
254
+ break;
255
+ case `Identifier`:
256
+ if (n.callee.name === `find`) {
257
+ willReport = true;
258
+ }
259
+ break;
260
+ }
261
+ if (willReport) {
262
+ context.report({
263
+ node: n,
264
+ message: `Using find in a transactor is not allowed in an immortal store.`
265
+ });
266
+ }
267
+ }
268
+ });
269
+ }
270
+ }
271
+ };
272
+ }
273
+ };
274
+
275
+ // eslint-plugin/src/rules/synchronous-selector-dependencies.ts
121
276
  var synchronousSelectorDependencies = {
122
277
  meta: {
123
278
  type: `problem`,
@@ -1,2 +1,3 @@
1
1
  export * from "./explicit-state-types"
2
+ export * from "./lifespan"
2
3
  export * from "./synchronous-selector-dependencies"
@@ -0,0 +1,204 @@
1
+ import type { Rule } from "eslint"
2
+ import type * as ESTree from "estree"
3
+
4
+ import { walk } from "../walk"
5
+
6
+ export const lifespan = {
7
+ meta: {
8
+ type: `problem`,
9
+ docs: {
10
+ description: `atom.io provides tools for short-lived (ephemeral) and long-lived (immortal) stores. This rule allows you to guard against unsafe usage of tools for the other type of store.`,
11
+ category: `Possible Errors`,
12
+ recommended: false,
13
+ url: ``, // URL to documentation page for this rule
14
+ },
15
+ schema: [
16
+ {
17
+ type: `string`,
18
+ enum: [`ephemeral`, `immortal`],
19
+ default: `ephemeral`,
20
+ },
21
+ ],
22
+ },
23
+ create(context) {
24
+ const storeLifespan = (context.options[0] ?? `ephemeral`) as
25
+ | `ephemeral`
26
+ | `immortal`
27
+ return {
28
+ ImportDeclaration(node) {
29
+ const importSource = node.source.value as string
30
+ if (!importSource.startsWith(`atom.io/`)) {
31
+ return
32
+ }
33
+ const [_, subPackageName] = importSource.split(`/`)
34
+ if (storeLifespan === `immortal` && subPackageName === `ephemeral`) {
35
+ context.report({
36
+ node,
37
+ message: `do not import from "${importSource}" in an ${storeLifespan} store`,
38
+ })
39
+ }
40
+ },
41
+
42
+ CallExpression(node) {
43
+ if (storeLifespan === `ephemeral`) {
44
+ return
45
+ }
46
+
47
+ const functionCallee =
48
+ node.callee.type === `Identifier` ? node.callee : undefined
49
+ const methodCallee =
50
+ node.callee.type === `MemberExpression` &&
51
+ node.callee.property.type === `Identifier`
52
+ ? node.callee.property
53
+ : undefined
54
+ const callee = functionCallee ?? methodCallee
55
+
56
+ if (callee === undefined) {
57
+ return
58
+ }
59
+
60
+ if (callee.name === `findState`) {
61
+ context.report({
62
+ node,
63
+ message: `do not use findState in an ${storeLifespan} store`,
64
+ })
65
+ }
66
+
67
+ const storeProcedures: (
68
+ | ESTree.ArrowFunctionExpression
69
+ | ESTree.FunctionExpression
70
+ )[] = []
71
+ if (
72
+ callee.name === `selector` ||
73
+ callee.name === `selectorFamily` ||
74
+ callee.name === `transaction`
75
+ ) {
76
+ if (node.arguments[0].type === `ObjectExpression`) {
77
+ const argProperties = node.arguments[0].properties
78
+ switch (callee.name) {
79
+ case `selector`:
80
+ case `selectorFamily`:
81
+ {
82
+ const getAndSetProps = argProperties.filter(
83
+ (prop): prop is ESTree.Property => {
84
+ return (
85
+ `key` in prop &&
86
+ `name` in prop.key &&
87
+ (prop.key.name === `get` || prop.key.name === `set`)
88
+ )
89
+ },
90
+ )
91
+ switch (callee.name) {
92
+ case `selector`:
93
+ {
94
+ for (const prop of getAndSetProps) {
95
+ if (
96
+ prop.value.type === `FunctionExpression` ||
97
+ prop.value.type === `ArrowFunctionExpression`
98
+ ) {
99
+ console.log(prop.value)
100
+ storeProcedures.push(prop.value)
101
+ }
102
+ }
103
+ }
104
+ break
105
+ case `selectorFamily`:
106
+ {
107
+ for (const prop of getAndSetProps) {
108
+ const { value } = prop
109
+ if (
110
+ value.type === `FunctionExpression` ||
111
+ value.type === `ArrowFunctionExpression`
112
+ ) {
113
+ if (value.body.type === `BlockStatement`) {
114
+ for (const statement of value.body.body) {
115
+ if (
116
+ statement.type === `ReturnStatement` &&
117
+ statement.argument &&
118
+ (statement.argument.type ===
119
+ `FunctionExpression` ||
120
+ statement.argument.type ===
121
+ `ArrowFunctionExpression`)
122
+ ) {
123
+ storeProcedures.push(statement.argument)
124
+ }
125
+ }
126
+ } else if (
127
+ value.body.type === `FunctionExpression` ||
128
+ value.body.type === `ArrowFunctionExpression`
129
+ ) {
130
+ storeProcedures.push(value.body)
131
+ }
132
+ }
133
+ }
134
+ }
135
+ break
136
+ }
137
+ }
138
+ break
139
+
140
+ case `transaction`:
141
+ {
142
+ const doProp = argProperties.find(
143
+ (prop): prop is ESTree.Property => {
144
+ return (
145
+ `key` in prop &&
146
+ `name` in prop.key &&
147
+ prop.key.name === `do`
148
+ )
149
+ },
150
+ )
151
+ if (doProp) {
152
+ if (
153
+ doProp.value.type === `FunctionExpression` ||
154
+ doProp.value.type === `ArrowFunctionExpression`
155
+ ) {
156
+ storeProcedures.push(doProp.value)
157
+ }
158
+ }
159
+ }
160
+ break
161
+ }
162
+ }
163
+ }
164
+
165
+ for (const storeProcedure of storeProcedures) {
166
+ const transactorsParam = storeProcedure.params[0]
167
+ const nonDestructuredTransactorsName =
168
+ transactorsParam && `name` in transactorsParam
169
+ ? transactorsParam.name
170
+ : undefined
171
+ walk(storeProcedure.body, (n) => {
172
+ // console.log(`${`\t`.repeat(depth)}${n.type} ${n.name ?? ``}`)
173
+ if (n.type === `CallExpression`) {
174
+ let willReport = false
175
+ switch (n.callee.type) {
176
+ case `MemberExpression`:
177
+ if (
178
+ n.callee.object.type === `Identifier` &&
179
+ n.callee.object.name === nonDestructuredTransactorsName &&
180
+ n.callee.property.type === `Identifier` &&
181
+ n.callee.property.name === `find`
182
+ ) {
183
+ willReport = true
184
+ }
185
+ break
186
+ case `Identifier`:
187
+ if (n.callee.name === `find`) {
188
+ willReport = true
189
+ }
190
+ break
191
+ }
192
+ if (willReport) {
193
+ context.report({
194
+ node: n,
195
+ message: `Using find in a transactor is not allowed in an immortal store.`,
196
+ })
197
+ }
198
+ }
199
+ })
200
+ }
201
+ },
202
+ }
203
+ },
204
+ } satisfies Rule.RuleModule
@@ -1,71 +1,7 @@
1
1
  import type { Rule } from "eslint"
2
2
  import type * as ESTree from "estree"
3
3
 
4
- function walk(
5
- node: ESTree.Node,
6
- callback: (node: ESTree.Node, depth: number) => void,
7
- depth = 0,
8
- ) {
9
- callback(node, depth)
10
-
11
- switch (node.type) {
12
- case `FunctionDeclaration`:
13
- case `FunctionExpression`:
14
- case `ArrowFunctionExpression`:
15
- for (const param of node.params) {
16
- walk(param, callback, depth + 1)
17
- }
18
- walk(node.body, callback, depth + 1)
19
- break
20
- case `BlockStatement`:
21
- for (const statement of node.body) {
22
- walk(statement, callback, depth + 1)
23
- }
24
- break
25
- case `IfStatement`:
26
- walk(node.test, callback, depth)
27
- walk(node.consequent, callback, depth)
28
- if (node.alternate) {
29
- walk(node.alternate, callback, depth)
30
- }
31
- break
32
- case `SwitchStatement`:
33
- walk(node.discriminant, callback, depth + 1)
34
- for (const caseOrDefault of node.cases) {
35
- walk(caseOrDefault, callback, depth)
36
- }
37
- break
38
- case `ReturnStatement`:
39
- if (node.argument) {
40
- walk(node.argument, callback, depth)
41
- }
42
- break
43
- case `SwitchCase`:
44
- if (node.test) {
45
- walk(node.test, callback, depth)
46
- }
47
- for (const statement of node.consequent) {
48
- walk(statement, callback, depth)
49
- }
50
- break
51
- case `VariableDeclaration`:
52
- for (const declaration of node.declarations) {
53
- walk(declaration, callback, depth)
54
- if (declaration.init) {
55
- walk(declaration.init, callback, depth)
56
- }
57
- }
58
- break
59
- case `BinaryExpression`:
60
- walk(node.left, callback, depth)
61
- walk(node.right, callback, depth)
62
- break
63
- case `MemberExpression`:
64
- walk(node.object, callback, depth)
65
- walk(node.property, callback, depth)
66
- break
67
- }
68
- }
4
+ import { walk } from "../walk"
69
5
 
70
6
  export const synchronousSelectorDependencies = {
71
7
  meta: {