mikser-io 11.3.1 → 11.3.2

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 (2) hide show
  1. package/package.json +1 -1
  2. package/testing/harness.js +21 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikser-io",
3
- "version": "11.3.1",
3
+ "version": "11.3.2",
4
4
  "files": [
5
5
  "app.js",
6
6
  "index.js",
@@ -9,6 +9,7 @@ import _ from 'lodash'
9
9
  import realRuntime from '../src/runtime.js'
10
10
  import { resetServices } from '../src/services.js'
11
11
  import { matchEntity, normalize, changeExtension, getFormatInfo, checksum, AbortError } from '../src/utils/index.js'
12
+ import sift from 'sift'
12
13
 
13
14
  const OPERATION = {
14
15
  CREATE: 'create',
@@ -130,6 +131,23 @@ export function createHarness({
130
131
  }
131
132
  }
132
133
 
134
+ // One matcher for findEntity / findEntities / iterateEntities, and it is
135
+ // sift — the same library catalog.js runs queries through, so a filter
136
+ // that works in a unit test works in a build.
137
+ //
138
+ // These used to compare `e[key] === value` per key, which silently matched
139
+ // NOTHING for any mongo-style operator: `{ collection: { $ne: 'assets' } }`
140
+ // tested a string against an object and every entity failed. A plugin
141
+ // walking the catalog that way got an empty result and no error, so its
142
+ // test either passed vacuously or failed somewhere far from the cause —
143
+ // which is what happened to the assets orphan sweep, whose whole job is
144
+ // deciding what has no source.
145
+ const matching = (query) => {
146
+ if (!query) return [...entities]
147
+ if (typeof query === 'function') return entities.filter(query)
148
+ return entities.filter(sift(query))
149
+ }
150
+
133
151
  const core = {
134
152
  runtime,
135
153
  useLogger: () => logger,
@@ -169,28 +187,19 @@ export function createHarness({
169
187
  findEntity: async (query) => {
170
188
  if (!query) return entities[0]
171
189
  if (typeof query === 'function') return entities.find(query)
172
- return entities.find(e => Object.entries(query).every(([k, v]) => e[k] === v))
190
+ return matching(query)[0]
173
191
  },
174
192
  // Synchronous PK lookup mirroring catalog.js's findById. Layouts'
175
193
  // onBeforeRender hydrates dispatch ids through this — the harness
176
194
  // serves from the same in-memory entities array.
177
195
  findById: (id) => entities.find(e => e?.id === id) ?? catalogStub.byId.get(id),
178
- findEntities: async (query) => {
179
- if (!query) return [...entities]
180
- if (typeof query === 'function') return entities.filter(query)
181
- return entities.filter(e => Object.entries(query).every(([k, v]) => e[k] === v))
182
- },
196
+ findEntities: async (query) => matching(query),
183
197
  iterateEntities: async function* (query) {
184
198
  // Stub — yields the same set findEntities would return,
185
199
  // one entity at a time. Real impl in catalog.js chunks via
186
200
  // sqlite; the harness doesn't need that fidelity because
187
201
  // unit-test corpora are tiny.
188
- const filtered = !query
189
- ? [...entities]
190
- : (typeof query === 'function'
191
- ? entities.filter(query)
192
- : entities.filter(e => Object.entries(query).every(([k, v]) => e[k] === v)))
193
- for (const e of filtered) yield e
202
+ for (const e of matching(query)) yield e
194
203
  },
195
204
 
196
205
  // Rendering & postprocessing — capture for assertions