circuitjson-toolkit 1.1.0 → 1.1.1
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/README.md
CHANGED
|
@@ -37,6 +37,12 @@ See the [migration guide](docs/migration.md) and its generated
|
|
|
37
37
|
[1.1.0 release notes](docs/release-notes-v1.1.0.md) provide the concise change
|
|
38
38
|
summary.
|
|
39
39
|
|
|
40
|
+
Version 1.1.1 makes queued worker-request ownership synchronous. Parser and
|
|
41
|
+
project requests waiting behind active work can no longer observe later
|
|
42
|
+
caller-buffer mutation; explicit transfers detach exact buffers immediately
|
|
43
|
+
after admission. See the
|
|
44
|
+
[1.1.1 release notes](docs/release-notes-v1.1.1.md).
|
|
45
|
+
|
|
40
46
|
Before 1.1.0:
|
|
41
47
|
|
|
42
48
|
```js
|
|
@@ -294,6 +300,7 @@ copy while keeping sync, direct async, and worker results mutation-isolated.
|
|
|
294
300
|
- [Model and envelope format](docs/model-format.md)
|
|
295
301
|
- [Testing and downstream conformance](docs/testing.md)
|
|
296
302
|
- [1.1.0 release notes](docs/release-notes-v1.1.0.md)
|
|
303
|
+
- [1.1.1 release notes](docs/release-notes-v1.1.1.md)
|
|
297
304
|
- [Library scope](spec/library-scope.md)
|
|
298
305
|
|
|
299
306
|
## Package scope
|
package/docs/api.md
CHANGED
|
@@ -80,6 +80,12 @@ Asynchronous parser and project calls accept:
|
|
|
80
80
|
unavailable. Protocol, post-message, parser, and runtime errors stay visible.
|
|
81
81
|
Worker and direct results have the same serialized shape.
|
|
82
82
|
|
|
83
|
+
Requests waiting behind active worker work take ownership immediately after
|
|
84
|
+
admission. The default mode clones the exact binary graph into a private queue
|
|
85
|
+
snapshot and leaves caller buffers intact. `transferInput: true` detaches exact
|
|
86
|
+
transferable buffers at admission; partial views, resizable buffers, and
|
|
87
|
+
shared buffers are isolated without detaching unrelated caller bytes.
|
|
88
|
+
|
|
83
89
|
`retainSource` is exactly `'none' | 'reference'` and defaults to `'none'`.
|
|
84
90
|
`'reference'` is an in-process parser option: the returned document has a
|
|
85
91
|
non-enumerable `sourceReference` property whose value is the exact caller input
|
package/docs/migration.md
CHANGED
|
@@ -92,6 +92,12 @@ returns either `{ ok: true, value }` or
|
|
|
92
92
|
uses ordered `detect`, `decode`, `project`, `validate`, and `complete`
|
|
93
93
|
stages. Cancellation is request-scoped.
|
|
94
94
|
|
|
95
|
+
Since 1.1.1, a request waiting behind active worker work is owned immediately
|
|
96
|
+
after admission. With the default `transferInput: false`, later caller
|
|
97
|
+
mutations cannot alter a queued parser input, project entry, or asset. With
|
|
98
|
+
`transferInput: true`, exact transferable buffers detach at admission;
|
|
99
|
+
partial, resizable, and shared ranges continue to use isolated copies.
|
|
100
|
+
|
|
95
101
|
## Package subpaths
|
|
96
102
|
|
|
97
103
|
- `circuitjson-toolkit/parser`
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# circuitjson-toolkit 1.1.1
|
|
2
|
+
|
|
3
|
+
## Synchronous queued-request ownership
|
|
4
|
+
|
|
5
|
+
This patch makes the common worker client own every accepted parser and
|
|
6
|
+
project request when it enters the queue behind active work.
|
|
7
|
+
|
|
8
|
+
- Default `transferInput: false` requests clone their exact binary graph into
|
|
9
|
+
a private queue snapshot immediately. Later caller mutation cannot change a
|
|
10
|
+
queued parser input, project entry, or attached asset.
|
|
11
|
+
- `transferInput: true` detaches exact transferable caller buffers immediately
|
|
12
|
+
after queue admission. Partial views, resizable buffers, and shared buffers
|
|
13
|
+
keep their isolated-copy behavior without detaching unrelated caller bytes.
|
|
14
|
+
- Shared backing-buffer aliases remain shared in the owned request, and queued
|
|
15
|
+
snapshots transfer to the worker without another binary copy when posted.
|
|
16
|
+
- Disposed, pre-cancelled, over-limit, and initial worker-construction failures
|
|
17
|
+
reject before ownership. Automatic direct fallback therefore retains valid
|
|
18
|
+
binary input.
|
|
19
|
+
- Parser and project queues use the same bounded, accessor-safe traversal and
|
|
20
|
+
retain existing cancellation, error, and response behavior.
|
|
21
|
+
|
|
22
|
+
Public names, parameters, package subpaths, document envelopes, and project
|
|
23
|
+
envelopes are unchanged from 1.1.0. Gerber, Altium, KiCad, viewers, and ECAD
|
|
24
|
+
Forge receive the corrected behavior through the shared `ParserWorkerClient`.
|
package/docs/testing.md
CHANGED
|
@@ -80,6 +80,11 @@ Worker checks install an in-memory `ecad-toolkit.worker.v1` loopback with real
|
|
|
80
80
|
structured-clone and transfer boundaries, then require `worker: true`. A direct
|
|
81
81
|
fallback cannot satisfy these checks.
|
|
82
82
|
|
|
83
|
+
Queue regressions hold one worker operation active while parser and project
|
|
84
|
+
requests wait behind it. They mutate default-mode caller buffers and require
|
|
85
|
+
the original request snapshot, then verify explicit-transfer buffers detach
|
|
86
|
+
only after admission and preserve shared backing-buffer aliases.
|
|
87
|
+
|
|
83
88
|
Extension ownership tests use a realistic native graph above the former
|
|
84
89
|
compact-metadata item ceiling. They require one bounded immutable capture,
|
|
85
90
|
mutation isolation, a direct capture under two seconds, exact worker-result
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circuitjson-toolkit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Canonical CircuitJSON parsing, project, rendering, query, manufacturing, simulation, and scene contracts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"circuitjson",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"docs/model-format.md",
|
|
52
52
|
"docs/provenance.md",
|
|
53
53
|
"docs/release-notes-v1.1.0.md",
|
|
54
|
+
"docs/release-notes-v1.1.1.md",
|
|
54
55
|
"docs/testing.md",
|
|
55
56
|
"spec",
|
|
56
57
|
"LICENSE",
|
|
@@ -232,6 +232,8 @@ export class ParserWorkerClient {
|
|
|
232
232
|
if (this.#pending.size >= MAX_PENDING_REQUESTS) {
|
|
233
233
|
throw ParserWorkerClient.#queueError()
|
|
234
234
|
}
|
|
235
|
+
const wasQueued = Boolean(this.#activeRequestId)
|
|
236
|
+
if (wasQueued) prepared = WorkerRequestData.ownForQueue(prepared)
|
|
235
237
|
const requestId = `worker-${this.#nextRequestId}`
|
|
236
238
|
this.#nextRequestId += 1
|
|
237
239
|
|
|
@@ -245,7 +247,7 @@ export class ParserWorkerClient {
|
|
|
245
247
|
onAbort: null,
|
|
246
248
|
onProgress: prepared.onProgress,
|
|
247
249
|
previousProgress: null,
|
|
248
|
-
attemptToken
|
|
250
|
+
attemptToken: wasQueued ? null : attemptToken
|
|
249
251
|
}
|
|
250
252
|
if (prepared.signal) {
|
|
251
253
|
pending.onAbort = () => this.cancel(requestId)
|
|
@@ -50,6 +50,7 @@ const DATA_VIEW_BYTE_OFFSET_GETTER = Object.getOwnPropertyDescriptor(
|
|
|
50
50
|
const DATA_VIEW_CONSTRUCTOR = DataView
|
|
51
51
|
const UINT8_ARRAY_CONSTRUCTOR = Uint8Array
|
|
52
52
|
const UINT8_ARRAY_SET = Uint8Array.prototype.set
|
|
53
|
+
const STRUCTURED_CLONE = globalThis.structuredClone
|
|
53
54
|
const MAX_REQUEST_BYTES = 100_000_000
|
|
54
55
|
const MAX_REQUEST_DEPTH = 64
|
|
55
56
|
const MAX_REQUEST_VALUES = 100_000
|
|
@@ -95,6 +96,32 @@ export class WorkerRequestData {
|
|
|
95
96
|
})
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Owns one already-prepared queued request and rebuilds its post transfer list.
|
|
101
|
+
* @param {{ payload: unknown, transfer: Transferable[] }} prepared Prepared request.
|
|
102
|
+
* @returns {Record<string, any>} Owned queued request.
|
|
103
|
+
*/
|
|
104
|
+
static ownForQueue(prepared) {
|
|
105
|
+
const owned = Reflect.apply(STRUCTURED_CLONE, undefined, [
|
|
106
|
+
prepared.payload,
|
|
107
|
+
{ transfer: prepared.transfer }
|
|
108
|
+
])
|
|
109
|
+
const posted = WorkerRequestData.#prepare(owned, {
|
|
110
|
+
bytes: MAX_REQUEST_BYTES,
|
|
111
|
+
copyBinary: false,
|
|
112
|
+
output: false,
|
|
113
|
+
strictDescriptors: false,
|
|
114
|
+
transferInput: true,
|
|
115
|
+
trustProof: false,
|
|
116
|
+
values: MAX_REQUEST_VALUES
|
|
117
|
+
})
|
|
118
|
+
return {
|
|
119
|
+
...prepared,
|
|
120
|
+
payload: posted.value,
|
|
121
|
+
transfer: posted.transfer
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
98
125
|
/**
|
|
99
126
|
* Prepares a bounded worker-owned result and transfers all safe buffers.
|
|
100
127
|
* @param {unknown} value Worker result.
|