@bldrs-ai/conway 1.509.1435 → 1.511.1441
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/compiled/examples/browser-bundled.cjs +410 -16
- package/compiled/examples/cli-bundled.cjs +544 -18
- package/compiled/examples/cli-step-bundled.cjs +312 -16
- package/compiled/examples/validator-bundled.cjs +410 -16
- package/compiled/src/compat/web-ifc/ifc_api.d.ts +33 -0
- package/compiled/src/compat/web-ifc/ifc_api.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api.js +47 -0
- package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.js +29 -0
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts +8 -0
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.d.ts +14 -0
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.js +33 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts +7 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.js +16 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts +64 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.js +293 -30
- package/compiled/src/compat/web-ifc/ifc_api_streamed_open.test.js +29 -0
- package/compiled/src/ifc/ifc_demand_extraction.test.js +12 -1
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts +35 -0
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_geometry_extraction.js +142 -2
- package/compiled/src/ifc/ifc_step_parser.d.ts +23 -1
- package/compiled/src/ifc/ifc_step_parser.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_step_parser.js +23 -1
- package/compiled/src/ifc/ifc_stream_open.d.ts +28 -1
- package/compiled/src/ifc/ifc_stream_open.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_stream_open.js +44 -1
- package/compiled/src/ifc/ifc_stream_open.test.js +10 -1
- package/compiled/src/index.d.ts +3 -2
- package/compiled/src/index.d.ts.map +1 -1
- package/compiled/src/index.js +3 -2
- package/compiled/src/namespace_surface.test.js +3 -0
- package/compiled/src/step/parsing/byte_source.d.ts +98 -0
- package/compiled/src/step/parsing/byte_source.d.ts.map +1 -1
- package/compiled/src/step/parsing/byte_source.js +71 -0
- package/compiled/src/step/parsing/byte_source.test.d.ts +2 -0
- package/compiled/src/step/parsing/byte_source.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/byte_source.test.js +47 -0
- package/compiled/src/step/parsing/byte_source_node.d.ts +41 -0
- package/compiled/src/step/parsing/byte_source_node.d.ts.map +1 -0
- package/compiled/src/step/parsing/byte_source_node.js +54 -0
- package/compiled/src/step/parsing/express_ref_scan.d.ts +20 -0
- package/compiled/src/step/parsing/express_ref_scan.d.ts.map +1 -0
- package/compiled/src/step/parsing/express_ref_scan.js +91 -0
- package/compiled/src/step/parsing/express_ref_scan.test.d.ts +2 -0
- package/compiled/src/step/parsing/express_ref_scan.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/express_ref_scan.test.js +28 -0
- package/compiled/src/step/parsing/step_parser.d.ts +7 -4
- package/compiled/src/step/parsing/step_parser.d.ts.map +1 -1
- package/compiled/src/step/parsing/step_parser.js +25 -6
- package/compiled/src/step/parsing/streaming_index_builder.d.ts +3 -3
- package/compiled/src/step/parsing/streaming_index_builder.d.ts.map +1 -1
- package/compiled/src/step/parsing/streaming_index_builder.js +27 -7
- package/compiled/src/step/parsing/streaming_index_builder_async.test.js +13 -1
- package/compiled/src/step/step_buffer_provider.d.ts +44 -0
- package/compiled/src/step/step_buffer_provider.d.ts.map +1 -1
- package/compiled/src/step/step_buffer_provider.js +56 -8
- package/compiled/src/step/step_buffer_provider.test.js +14 -0
- package/compiled/src/step/step_entity_base.d.ts +15 -0
- package/compiled/src/step/step_entity_base.d.ts.map +1 -1
- package/compiled/src/step/step_entity_base.js +33 -0
- package/compiled/src/step/step_model_base.d.ts +62 -0
- package/compiled/src/step/step_model_base.d.ts.map +1 -1
- package/compiled/src/step/step_model_base.js +136 -0
- package/compiled/src/stream/index.d.ts +3 -2
- package/compiled/src/stream/index.d.ts.map +1 -1
- package/compiled/src/stream/index.js +3 -2
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* eslint-disable no-magic-numbers */
|
|
2
|
+
import { describe, expect, test } from "@jest/globals";
|
|
3
|
+
import { BufferByteSource, StoreByteSource, SyncAccessHandleByteSource, } from "./byte_source.js";
|
|
4
|
+
import { InMemoryStepByteStore } from "../step_buffer_provider.js";
|
|
5
|
+
import { FileDescriptorByteSource } from "./byte_source_node.js";
|
|
6
|
+
describe("ByteSource implementations", () => {
|
|
7
|
+
const bytes = new Uint8Array([10, 20, 30, 40, 50]);
|
|
8
|
+
test("BufferByteSource copies a range", () => {
|
|
9
|
+
const source = new BufferByteSource(bytes);
|
|
10
|
+
const into = new Uint8Array(4);
|
|
11
|
+
expect(source.read(1, 3, into, 1)).toBe(3);
|
|
12
|
+
expect([...into]).toEqual([0, 20, 30, 40]);
|
|
13
|
+
});
|
|
14
|
+
test("StoreByteSource matches BufferByteSource over the same bytes", async () => {
|
|
15
|
+
const source = new StoreByteSource(new InMemoryStepByteStore(bytes));
|
|
16
|
+
const into = new Uint8Array(3);
|
|
17
|
+
expect(await source.read(2, 10, into, 0)).toBe(3);
|
|
18
|
+
expect([...into]).toEqual([30, 40, 50]);
|
|
19
|
+
});
|
|
20
|
+
test("SyncAccessHandleByteSource reads through the handle contract", () => {
|
|
21
|
+
const handle = {
|
|
22
|
+
getSize: () => bytes.length,
|
|
23
|
+
read(buffer, options) {
|
|
24
|
+
const at = options?.at ?? 0;
|
|
25
|
+
const want = Math.min(buffer.length, bytes.length - at);
|
|
26
|
+
buffer.set(bytes.subarray(at, at + want));
|
|
27
|
+
return want;
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const source = new SyncAccessHandleByteSource(handle);
|
|
31
|
+
const into = new Uint8Array(2);
|
|
32
|
+
expect(source.read(3, 2, into, 0)).toBe(2);
|
|
33
|
+
expect([...into]).toEqual([40, 50]);
|
|
34
|
+
});
|
|
35
|
+
test("FileDescriptorByteSource reads index.ifc without holding it", () => {
|
|
36
|
+
const source = FileDescriptorByteSource.open("data/index.ifc");
|
|
37
|
+
try {
|
|
38
|
+
const head = new Uint8Array(15);
|
|
39
|
+
const got = source.read(0, 15, head, 0);
|
|
40
|
+
expect(got).toBe(15);
|
|
41
|
+
expect(new TextDecoder().decode(head).startsWith("ISO-10303-21;")).toBe(true);
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
source.close();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ByteSource } from "./byte_source.js";
|
|
2
|
+
/**
|
|
3
|
+
* A `ByteSource` over a Node file descriptor — the node/test twin of
|
|
4
|
+
* `SyncAccessHandleByteSource`. The file is never held as one JS
|
|
5
|
+
* buffer; each `read` is `fs.readSync` into the caller's window.
|
|
6
|
+
*
|
|
7
|
+
* The caller owns the fd (open + close). This class does not close it.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FileDescriptorByteSource implements ByteSource {
|
|
10
|
+
private readonly fd_;
|
|
11
|
+
private readonly byteLength_;
|
|
12
|
+
/**
|
|
13
|
+
* @param fd_ An fd open for reading.
|
|
14
|
+
* @param byteLength_ File size in bytes (`fstat.size`).
|
|
15
|
+
*/
|
|
16
|
+
constructor(fd_: number, byteLength_: number);
|
|
17
|
+
/**
|
|
18
|
+
* Open `path` read-only and wrap it. Caller must {@link close}.
|
|
19
|
+
*
|
|
20
|
+
* @param path Filesystem path.
|
|
21
|
+
* @return {FileDescriptorByteSource} The source.
|
|
22
|
+
*/
|
|
23
|
+
static open(path: string): FileDescriptorByteSource;
|
|
24
|
+
/**
|
|
25
|
+
* @return {number} The file length.
|
|
26
|
+
*/
|
|
27
|
+
get byteLength(): number;
|
|
28
|
+
/**
|
|
29
|
+
* Close the underlying fd. Further reads throw.
|
|
30
|
+
*/
|
|
31
|
+
close(): void;
|
|
32
|
+
/**
|
|
33
|
+
* @param offset Absolute source offset to read from.
|
|
34
|
+
* @param length Maximum number of bytes to read.
|
|
35
|
+
* @param into Destination buffer.
|
|
36
|
+
* @param intoOffset Offset within `into` to write at.
|
|
37
|
+
* @return {number} The number of bytes copied.
|
|
38
|
+
*/
|
|
39
|
+
read(offset: number, length: number, into: Uint8Array, intoOffset: number): number;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=byte_source_node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byte_source_node.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/byte_source_node.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAG1C;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,UAAU;IAOrD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW;IANhC;;;OAGG;gBAEkB,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM;IAExC;;;;;OAKG;WACW,IAAI,CAAE,IAAI,EAAE,MAAM,GAAI,wBAAwB;IAO5D;;OAEG;IACH,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED;;OAEG;IACI,KAAK,IAAI,IAAI;IAIpB;;;;;;OAMG;IACI,IAAI,CACP,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAI,MAAM;CAUnF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
/**
|
|
3
|
+
* A `ByteSource` over a Node file descriptor — the node/test twin of
|
|
4
|
+
* `SyncAccessHandleByteSource`. The file is never held as one JS
|
|
5
|
+
* buffer; each `read` is `fs.readSync` into the caller's window.
|
|
6
|
+
*
|
|
7
|
+
* The caller owns the fd (open + close). This class does not close it.
|
|
8
|
+
*/
|
|
9
|
+
export class FileDescriptorByteSource {
|
|
10
|
+
/**
|
|
11
|
+
* @param fd_ An fd open for reading.
|
|
12
|
+
* @param byteLength_ File size in bytes (`fstat.size`).
|
|
13
|
+
*/
|
|
14
|
+
constructor(fd_, byteLength_) {
|
|
15
|
+
this.fd_ = fd_;
|
|
16
|
+
this.byteLength_ = byteLength_;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Open `path` read-only and wrap it. Caller must {@link close}.
|
|
20
|
+
*
|
|
21
|
+
* @param path Filesystem path.
|
|
22
|
+
* @return {FileDescriptorByteSource} The source.
|
|
23
|
+
*/
|
|
24
|
+
static open(path) {
|
|
25
|
+
const fd = fs.openSync(path, 'r');
|
|
26
|
+
return new FileDescriptorByteSource(fd, fs.fstatSync(fd).size);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @return {number} The file length.
|
|
30
|
+
*/
|
|
31
|
+
get byteLength() {
|
|
32
|
+
return this.byteLength_;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Close the underlying fd. Further reads throw.
|
|
36
|
+
*/
|
|
37
|
+
close() {
|
|
38
|
+
fs.closeSync(this.fd_);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* @param offset Absolute source offset to read from.
|
|
42
|
+
* @param length Maximum number of bytes to read.
|
|
43
|
+
* @param into Destination buffer.
|
|
44
|
+
* @param intoOffset Offset within `into` to write at.
|
|
45
|
+
* @return {number} The number of bytes copied.
|
|
46
|
+
*/
|
|
47
|
+
read(offset, length, into, intoOffset) {
|
|
48
|
+
const end = Math.min(offset + length, this.byteLength_);
|
|
49
|
+
if (end <= offset) {
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
return fs.readSync(this.fd_, into, intoOffset, end - offset, offset);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lexical scan of a STEP record for `#<expressID>` references.
|
|
3
|
+
*
|
|
4
|
+
* Used to prefetch the source-byte closure a windowed extract will
|
|
5
|
+
* acquire: walking typed attributes requires those records to already
|
|
6
|
+
* be resident, so the walk has to happen on the raw text. Strings
|
|
7
|
+
* (`'...'` with `''` escapes), binary blobs (`"..."`) and C-style
|
|
8
|
+
* comments are skipped so a hash inside a string is not a ref.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Collect the distinct express IDs referenced from a STEP record's
|
|
12
|
+
* bytes. Order is first-seen; `#0` is ignored (not a real entity).
|
|
13
|
+
*
|
|
14
|
+
* @param bytes The record text (or a view containing it).
|
|
15
|
+
* @param from Start offset within `bytes`.
|
|
16
|
+
* @param length Number of bytes to scan.
|
|
17
|
+
* @return {number[]} Distinct referenced express IDs.
|
|
18
|
+
*/
|
|
19
|
+
export declare function scanExpressRefs(bytes: Uint8Array, from?: number, length?: number): number[];
|
|
20
|
+
//# sourceMappingURL=express_ref_scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express_ref_scan.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/express_ref_scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,MAAU,EAAE,MAAM,GAAE,MAA4B,GAAI,MAAM,EAAE,CA8DxF"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lexical scan of a STEP record for `#<expressID>` references.
|
|
3
|
+
*
|
|
4
|
+
* Used to prefetch the source-byte closure a windowed extract will
|
|
5
|
+
* acquire: walking typed attributes requires those records to already
|
|
6
|
+
* be resident, so the walk has to happen on the raw text. Strings
|
|
7
|
+
* (`'...'` with `''` escapes), binary blobs (`"..."`) and C-style
|
|
8
|
+
* comments are skipped so a hash inside a string is not a ref.
|
|
9
|
+
*/
|
|
10
|
+
const HASH = 0x23;
|
|
11
|
+
const QUOTE = 0x27;
|
|
12
|
+
const DQUOTE = 0x22;
|
|
13
|
+
const ZERO = 0x30;
|
|
14
|
+
const NINE = 0x39;
|
|
15
|
+
const SLASH = 0x2F;
|
|
16
|
+
const STAR = 0x2A;
|
|
17
|
+
/**
|
|
18
|
+
* Collect the distinct express IDs referenced from a STEP record's
|
|
19
|
+
* bytes. Order is first-seen; `#0` is ignored (not a real entity).
|
|
20
|
+
*
|
|
21
|
+
* @param bytes The record text (or a view containing it).
|
|
22
|
+
* @param from Start offset within `bytes`.
|
|
23
|
+
* @param length Number of bytes to scan.
|
|
24
|
+
* @return {number[]} Distinct referenced express IDs.
|
|
25
|
+
*/
|
|
26
|
+
export function scanExpressRefs(bytes, from = 0, length = bytes.length - from) {
|
|
27
|
+
const refs = [];
|
|
28
|
+
const seen = new Set();
|
|
29
|
+
const end = Math.min(from + length, bytes.length);
|
|
30
|
+
let cursor = from;
|
|
31
|
+
while (cursor < end) {
|
|
32
|
+
const byte = bytes[cursor];
|
|
33
|
+
if (byte === QUOTE) {
|
|
34
|
+
cursor = skipQuoted_(bytes, cursor + 1, end, QUOTE, true);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (byte === DQUOTE) {
|
|
38
|
+
cursor = skipQuoted_(bytes, cursor + 1, end, DQUOTE, false);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (byte === SLASH && cursor + 1 < end && bytes[cursor + 1] === STAR) {
|
|
42
|
+
cursor += 2;
|
|
43
|
+
while (cursor + 1 < end &&
|
|
44
|
+
!(bytes[cursor] === STAR && bytes[cursor + 1] === SLASH)) {
|
|
45
|
+
++cursor;
|
|
46
|
+
}
|
|
47
|
+
cursor += 2;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (byte === HASH) {
|
|
51
|
+
let value = 0;
|
|
52
|
+
let digit = cursor + 1;
|
|
53
|
+
while (digit < end && bytes[digit] >= ZERO && bytes[digit] <= NINE) {
|
|
54
|
+
value = (value * 10) + (bytes[digit] - ZERO);
|
|
55
|
+
++digit;
|
|
56
|
+
}
|
|
57
|
+
if (digit > cursor + 1 && value !== 0 && !seen.has(value)) {
|
|
58
|
+
seen.add(value);
|
|
59
|
+
refs.push(value);
|
|
60
|
+
}
|
|
61
|
+
cursor = digit;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
++cursor;
|
|
65
|
+
}
|
|
66
|
+
return refs;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Advance past a quoted span that started just before `from`.
|
|
70
|
+
*
|
|
71
|
+
* @param bytes Source bytes.
|
|
72
|
+
* @param from First byte after the opening quote.
|
|
73
|
+
* @param end Exclusive scan limit.
|
|
74
|
+
* @param quote The quote byte to match.
|
|
75
|
+
* @param doubledEscape True for STEP strings (`''` is one quote).
|
|
76
|
+
* @return {number} Index just after the closing quote (or `end`).
|
|
77
|
+
*/
|
|
78
|
+
function skipQuoted_(bytes, from, end, quote, doubledEscape) {
|
|
79
|
+
let cursor = from;
|
|
80
|
+
while (cursor < end) {
|
|
81
|
+
if (bytes[cursor] === quote) {
|
|
82
|
+
if (doubledEscape && cursor + 1 < end && bytes[cursor + 1] === quote) {
|
|
83
|
+
cursor += 2;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
return cursor + 1;
|
|
87
|
+
}
|
|
88
|
+
++cursor;
|
|
89
|
+
}
|
|
90
|
+
return end;
|
|
91
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express_ref_scan.test.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/express_ref_scan.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* eslint-disable no-magic-numbers */
|
|
2
|
+
import { describe, expect, test } from "@jest/globals";
|
|
3
|
+
import { scanExpressRefs } from "./express_ref_scan.js";
|
|
4
|
+
/**
|
|
5
|
+
* @param text STEP text to scan.
|
|
6
|
+
* @return {number[]} Referenced express IDs.
|
|
7
|
+
*/
|
|
8
|
+
function scan(text) {
|
|
9
|
+
return scanExpressRefs(new TextEncoder().encode(text));
|
|
10
|
+
}
|
|
11
|
+
describe("scanExpressRefs", () => {
|
|
12
|
+
test("collects distinct #ids in first-seen order", () => {
|
|
13
|
+
expect(scan("#10=IFCWALL(#20,#20,#30);")).toEqual([10, 20, 30]);
|
|
14
|
+
});
|
|
15
|
+
test("ignores hashes inside STEP strings and doubled quotes", () => {
|
|
16
|
+
expect(scan("#1=IFCLABEL('door #99 is fine');#2=IFCNAME('it''s #8');"))
|
|
17
|
+
.toEqual([1, 2]);
|
|
18
|
+
});
|
|
19
|
+
test("ignores hashes inside binary blobs", () => {
|
|
20
|
+
expect(scan("#1=IFCBLOB(\"#99DEAD\");")).toEqual([1]);
|
|
21
|
+
});
|
|
22
|
+
test("ignores hashes inside comments", () => {
|
|
23
|
+
expect(scan("#1=IFCWALL(/* see #99 */#2);")).toEqual([1, 2]);
|
|
24
|
+
});
|
|
25
|
+
test("skips #0", () => {
|
|
26
|
+
expect(scan("#1=IFCWALL(#0,#2);")).toEqual([1, 2]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -146,7 +146,8 @@ export default class StepParser<TypeIDType> extends StepHeaderParser {
|
|
|
146
146
|
*
|
|
147
147
|
* @param input The input parsing buffer, positioned at the data section.
|
|
148
148
|
* @param onRecordBoundary Called at each top-level record boundary with the
|
|
149
|
-
* buffer; the callback may rebase the buffer's window in place.
|
|
149
|
+
* buffer; the callback may rebase the buffer's window in place. Must be
|
|
150
|
+
* synchronous on this driver — a returned Promise is a caller bug.
|
|
150
151
|
* @param onRecordIndexed Called as each top-level record is indexed, with
|
|
151
152
|
* its localID, expressID and typeID (0 for external-mapping records) — the
|
|
152
153
|
* seam for incremental semantic consumers (type index, roots registry,
|
|
@@ -155,7 +156,7 @@ export default class StepParser<TypeIDType> extends StepHeaderParser {
|
|
|
155
156
|
* @param onProgress Optional byte-cursor progress callback.
|
|
156
157
|
* @return {BlockParseResult} The parsing result, including the index and result enum.
|
|
157
158
|
*/
|
|
158
|
-
parseDataBlockStreamed(input: ParsingBuffer, onRecordBoundary: (input: ParsingBuffer) => void
|
|
159
|
+
parseDataBlockStreamed(input: ParsingBuffer, onRecordBoundary: (input: ParsingBuffer) => void | Promise<void>, onRecordIndexed?: (localID: number, expressID: number, typeID: TypeIDType | undefined) => void, onProgress?: ParseProgressCallback, sink?: StepIndexSink<TypeIDType>): BlockParseResult<TypeIDType>;
|
|
159
160
|
/**
|
|
160
161
|
* Cooperative variant of parseDataBlockStreamed: identical parse and
|
|
161
162
|
* window-slide behaviour (same generator body, same boundary callback),
|
|
@@ -165,7 +166,9 @@ export default class StepParser<TypeIDType> extends StepHeaderParser {
|
|
|
165
166
|
*
|
|
166
167
|
* @param input The input parsing buffer, positioned at the data section.
|
|
167
168
|
* @param onRecordBoundary Called at each top-level record boundary with the
|
|
168
|
-
* buffer; the callback may rebase the buffer's window in place.
|
|
169
|
+
* buffer; the callback may rebase the buffer's window in place. May return
|
|
170
|
+
* a Promise when the slide itself is I/O (an async ByteSource); this
|
|
171
|
+
* driver awaits it before the next record is lexed.
|
|
169
172
|
* @param onRecordIndexed Called as each top-level record is indexed — see
|
|
170
173
|
* parseDataBlockStreamed.
|
|
171
174
|
* @param onProgress Optional byte-cursor progress callback.
|
|
@@ -174,7 +177,7 @@ export default class StepParser<TypeIDType> extends StepHeaderParser {
|
|
|
174
177
|
* @return {Promise<BlockParseResult>} The parsing result, including the
|
|
175
178
|
* index and result enum.
|
|
176
179
|
*/
|
|
177
|
-
parseDataBlockStreamedAsync(input: ParsingBuffer, onRecordBoundary: (input: ParsingBuffer) => void
|
|
180
|
+
parseDataBlockStreamedAsync(input: ParsingBuffer, onRecordBoundary: (input: ParsingBuffer) => void | Promise<void>, onRecordIndexed?: (localID: number, expressID: number, typeID: TypeIDType | undefined) => void, onProgress?: ParseProgressCallback, sink?: StepIndexSink<TypeIDType>, yieldIntervalMs?: number): Promise<BlockParseResult<TypeIDType>>;
|
|
178
181
|
/**
|
|
179
182
|
* Cooperative variant of parseDataBlock: identical parse (same generator
|
|
180
183
|
* body), but periodically awaits a macrotask so the event loop can run —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step_parser.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_parser.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"step_parser.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_parser.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,2BAA2B,CAAA;AAEjD,OAAO,aAAa,MAAM,8BAA8B,CAAA;AAcxD,OAAO,iBAAiB,EAAE,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEpE,MAAM,WAAW,kBAAkB,CAAC,UAAU;IAE5C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAA;IAE/C,cAAc,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAA;CACpD;AAED,MAAM,WAAW,oBAAoB,CAAC,UAAU,CAAE,SAAQ,kBAAkB,CAAC,UAAU,CAAC;IAEtF,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED,MAAM,WAAW,cAAc,CAAC,UAAU,CAAE,SAAQ,kBAAkB,CAAC,UAAU,CAAC;IAEhF,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,SAAS,CAAC,UAAU;IAEnC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,CAAA;CAEvC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,UAAU;IAEvC;;;;;OAKG;IACH,YAAY,CAAE,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,GAAI,IAAI,CAAA;IAEvD;;;OAGG;IACH,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,GAAG,CAAA;CACX;AAID;;GAEG;AAGH,oBAAY,WAAW;IAErB,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,YAAY,IAAI;IAChB,YAAY,IAAI;IAChB,YAAY,IAAI;CACjB;AAyBD,MAAM,MAAM,gBAAgB,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAA;AAC/E,MAAM,MAAM,uBAAuB,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAA;AAEtF;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAE,WAAW,EAAE,MAAM,KAAM,IAAI,CAAA;AAWnE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;AAGzD;;GAEG;AACH,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAkB;IAE3C;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,gBAAgB,CAQ7C;IAED;;;;;OAKG;IACI,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB;CA0L5D;AACD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU,CAAC,UAAU,CAAE,SAAQ,gBAAgB;IAQtD,OAAO,CAAC,QAAQ,CAAC,MAAM;IANnC;;;;;OAKG;gBAC0B,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAKpE;;;;;;;;;;;;;OAaG;IACI,gBAAgB,CACnB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IA+D9E;;;;;;;;;;OAUG;IACI,cAAc,CACjB,KAAK,EAAE,aAAa,EACpB,UAAU,CAAC,EAAE,qBAAqB,GAAI,gBAAgB,CAAC,UAAU,CAAC;IAkBtE;;;;;;;;;;;;;;;;;;OAkBG;IACI,sBAAsB,CACzB,KAAK,EAAE,aAAa,EACpB,gBAAgB,EAAE,CAAE,KAAK,EAAE,aAAa,KAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAClE,eAAe,CAAC,EAAE,CAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,KAAM,IAAI,EAChG,UAAU,CAAC,EAAE,qBAAqB,EAClC,IAAI,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,GAAI,gBAAgB,CAAC,UAAU,CAAC;IAsBpE;;;;;;;;;;;;;;;;;;;OAmBG;IACU,2BAA2B,CACpC,KAAK,EAAE,aAAa,EACpB,gBAAgB,EAAE,CAAE,KAAK,EAAE,aAAa,KAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAClE,eAAe,CAAC,EAAE,CAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,KAAM,IAAI,EAChG,UAAU,CAAC,EAAE,qBAAqB,EAClC,IAAI,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,EAChC,eAAe,GAAE,MAAwC,GACzD,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IA6BzC;;;;;;;;;;;OAWG;IACU,mBAAmB,CAC5B,KAAK,EAAE,aAAa,EACpB,UAAU,CAAC,EAAE,qBAAqB,EAClC,eAAe,GAAE,MAAwC,GACzD,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAyBzC;;;;;;;;;OASG;IACH,OAAO,CAAE,yBAAyB;IA+dlC;;;;;;;OAOG;IACI,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC;CAiarF"}
|
|
@@ -307,7 +307,9 @@ export default class StepParser extends StepHeaderParser {
|
|
|
307
307
|
if (next.done === true) {
|
|
308
308
|
return next.value;
|
|
309
309
|
}
|
|
310
|
-
|
|
310
|
+
if (typeof next.value === "number") {
|
|
311
|
+
onProgress?.(next.value);
|
|
312
|
+
}
|
|
311
313
|
}
|
|
312
314
|
}
|
|
313
315
|
/**
|
|
@@ -319,7 +321,8 @@ export default class StepParser extends StepHeaderParser {
|
|
|
319
321
|
*
|
|
320
322
|
* @param input The input parsing buffer, positioned at the data section.
|
|
321
323
|
* @param onRecordBoundary Called at each top-level record boundary with the
|
|
322
|
-
* buffer; the callback may rebase the buffer's window in place.
|
|
324
|
+
* buffer; the callback may rebase the buffer's window in place. Must be
|
|
325
|
+
* synchronous on this driver — a returned Promise is a caller bug.
|
|
323
326
|
* @param onRecordIndexed Called as each top-level record is indexed, with
|
|
324
327
|
* its localID, expressID and typeID (0 for external-mapping records) — the
|
|
325
328
|
* seam for incremental semantic consumers (type index, roots registry,
|
|
@@ -335,6 +338,9 @@ export default class StepParser extends StepHeaderParser {
|
|
|
335
338
|
if (next.done === true) {
|
|
336
339
|
return next.value;
|
|
337
340
|
}
|
|
341
|
+
if (typeof next.value !== "number") {
|
|
342
|
+
throw new Error("parseDataBlockStreamed: async window slide requires parseDataBlockStreamedAsync");
|
|
343
|
+
}
|
|
338
344
|
onProgress?.(next.value);
|
|
339
345
|
}
|
|
340
346
|
}
|
|
@@ -347,7 +353,9 @@ export default class StepParser extends StepHeaderParser {
|
|
|
347
353
|
*
|
|
348
354
|
* @param input The input parsing buffer, positioned at the data section.
|
|
349
355
|
* @param onRecordBoundary Called at each top-level record boundary with the
|
|
350
|
-
* buffer; the callback may rebase the buffer's window in place.
|
|
356
|
+
* buffer; the callback may rebase the buffer's window in place. May return
|
|
357
|
+
* a Promise when the slide itself is I/O (an async ByteSource); this
|
|
358
|
+
* driver awaits it before the next record is lexed.
|
|
351
359
|
* @param onRecordIndexed Called as each top-level record is indexed — see
|
|
352
360
|
* parseDataBlockStreamed.
|
|
353
361
|
* @param onProgress Optional byte-cursor progress callback.
|
|
@@ -364,6 +372,10 @@ export default class StepParser extends StepHeaderParser {
|
|
|
364
372
|
if (next.done === true) {
|
|
365
373
|
return next.value;
|
|
366
374
|
}
|
|
375
|
+
if (typeof next.value !== "number") {
|
|
376
|
+
await next.value;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
367
379
|
onProgress?.(next.value);
|
|
368
380
|
if (Date.now() - lastYield >= yieldIntervalMs) {
|
|
369
381
|
await yieldToEventLoop();
|
|
@@ -391,7 +403,9 @@ export default class StepParser extends StepHeaderParser {
|
|
|
391
403
|
if (next.done === true) {
|
|
392
404
|
return next.value;
|
|
393
405
|
}
|
|
394
|
-
|
|
406
|
+
if (typeof next.value === "number") {
|
|
407
|
+
onProgress?.(next.value);
|
|
408
|
+
}
|
|
395
409
|
if (Date.now() - lastYield >= yieldIntervalMs) {
|
|
396
410
|
await yieldToEventLoop();
|
|
397
411
|
lastYield = Date.now();
|
|
@@ -569,8 +583,13 @@ export default class StepParser extends StepHeaderParser {
|
|
|
569
583
|
// Top-level record boundary: the rewind stack is empty and the cursor
|
|
570
584
|
// sits at the next record's leading whitespace/`#`. A streaming driver
|
|
571
585
|
// uses this to slide its moving window forward (see
|
|
572
|
-
// streaming_index_builder.ts). No-op on the resident path.
|
|
573
|
-
|
|
586
|
+
// streaming_index_builder.ts). No-op on the resident path. An async
|
|
587
|
+
// slide (OPFS File.slice / HTTP range) is yielded so the async
|
|
588
|
+
// driver can await it before the next record is lexed.
|
|
589
|
+
const slide = onRecordBoundary?.(input);
|
|
590
|
+
if (slide !== void 0 && typeof slide.then === "function") {
|
|
591
|
+
yield slide;
|
|
592
|
+
}
|
|
574
593
|
if (!charws(HASH)) {
|
|
575
594
|
if (tokenws(END_SECTION)) {
|
|
576
595
|
return parseResult(ParseResult.COMPLETE);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ByteSource } from "./byte_source.js";
|
|
1
|
+
import { ByteSource, ReadableByteSource } from "./byte_source.js";
|
|
2
2
|
import { StepIndexColumns } from "./columnar_index.js";
|
|
3
3
|
import StepParser, { ParseResult, StepHeader, StepIndexEntry, StepIndexSink } from "./step_parser.js";
|
|
4
4
|
/**
|
|
@@ -87,7 +87,7 @@ export declare function buildIndexStreaming<TypeIDType>(source: ByteSource, pars
|
|
|
87
87
|
* @return {Promise<StreamingIndexResult>} The index, header, result and
|
|
88
88
|
* diagnostics.
|
|
89
89
|
*/
|
|
90
|
-
export declare function buildIndexStreamingAsync<TypeIDType>(source:
|
|
90
|
+
export declare function buildIndexStreamingAsync<TypeIDType>(source: ReadableByteSource, parser: StepParser<TypeIDType>, pool: number, onRecordIndexed?: (localID: number, expressID: number, typeID: TypeIDType | undefined) => void, sink?: StepIndexSink<TypeIDType>, onProgress?: (absoluteByteCursor: number) => void, yieldIntervalMs?: number): Promise<StreamingIndexResult<TypeIDType>>;
|
|
91
91
|
/**
|
|
92
92
|
* The output of a columnar streaming index build: the index in its SoA
|
|
93
93
|
* column form (no object phase — see columnar_index.ts), plus the header and
|
|
@@ -129,5 +129,5 @@ export declare function buildColumnarIndexStreaming<TypeIDType extends number>(s
|
|
|
129
129
|
* @return {Promise<StreamingColumnarIndexResult>} Columns, header, result,
|
|
130
130
|
* stats.
|
|
131
131
|
*/
|
|
132
|
-
export declare function buildColumnarIndexStreamingAsync<TypeIDType extends number>(source:
|
|
132
|
+
export declare function buildColumnarIndexStreamingAsync<TypeIDType extends number>(source: ReadableByteSource, parser: StepParser<TypeIDType>, pool: number, onRecordIndexed?: (localID: number, expressID: number, typeID: TypeIDType | undefined) => void, onProgress?: (absoluteByteCursor: number) => void, yieldIntervalMs?: number): Promise<StreamingColumnarIndexResult<TypeIDType>>;
|
|
133
133
|
//# sourceMappingURL=streaming_index_builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streaming_index_builder.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/streaming_index_builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"streaming_index_builder.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/streaming_index_builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -125,6 +125,21 @@ export function buildIndexStreaming(source, parser, pool, onRecordIndexed, sink)
|
|
|
125
125
|
// many slides on a small fixture; the pool sweep uses ≥ 128 KB anyway.
|
|
126
126
|
// eslint-disable-next-line no-magic-numbers
|
|
127
127
|
const MIN_WINDOW = 4 * 1024;
|
|
128
|
+
/**
|
|
129
|
+
* Fill `into` from either a sync or async byte source. A sync `read`
|
|
130
|
+
* resolves immediately; this is what lets the cooperative builder
|
|
131
|
+
* parse from an OPFS `File.slice()` store without a worker.
|
|
132
|
+
*
|
|
133
|
+
* @param source Sync or async positioned source.
|
|
134
|
+
* @param offset Absolute source offset.
|
|
135
|
+
* @param length Maximum bytes to copy.
|
|
136
|
+
* @param into Destination buffer.
|
|
137
|
+
* @param intoOffset Offset within `into`.
|
|
138
|
+
* @return {Promise<number>} Bytes copied.
|
|
139
|
+
*/
|
|
140
|
+
async function readSource(source, offset, length, into, intoOffset) {
|
|
141
|
+
return await source.read(offset, length, into, intoOffset);
|
|
142
|
+
}
|
|
128
143
|
/**
|
|
129
144
|
* Cooperative twin of {@link buildIndexStreaming}: identical parse, window
|
|
130
145
|
* and grow-and-restart behaviour (mirrored the same way the parser mirrors
|
|
@@ -150,7 +165,7 @@ export async function buildIndexStreamingAsync(source, parser, pool, onRecordInd
|
|
|
150
165
|
for (;;) {
|
|
151
166
|
const window = new Uint8Array(windowBytes);
|
|
152
167
|
let windowStartFile = 0;
|
|
153
|
-
let windowLen = source
|
|
168
|
+
let windowLen = await readSource(source, 0, windowBytes, window, 0);
|
|
154
169
|
let bytesRead = windowLen;
|
|
155
170
|
const input = new ParsingBuffer(window, 0, windowLen);
|
|
156
171
|
const [header, headerResult] = parser.parseHeader(input);
|
|
@@ -183,12 +198,17 @@ export async function buildIndexStreamingAsync(source, parser, pool, onRecordInd
|
|
|
183
198
|
const tail = windowLen - cursor;
|
|
184
199
|
window.copyWithin(0, cursor, windowLen);
|
|
185
200
|
const want = windowBytes - tail;
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
201
|
+
const fillAt = windowStartFile + windowLen;
|
|
202
|
+
// Only return a Promise when this boundary actually slides —
|
|
203
|
+
// an `async` callback would force an await at every record
|
|
204
|
+
// (millions of hops on a PSB-class file).
|
|
205
|
+
return readSource(source, fillAt, want, window, tail).then((got) => {
|
|
206
|
+
bytesRead += got;
|
|
207
|
+
windowLen = tail + got;
|
|
208
|
+
windowStartFile = recordFileStart;
|
|
209
|
+
buffer.rebaseWindow(window, 0, windowLen, windowStartFile);
|
|
210
|
+
++slides;
|
|
211
|
+
});
|
|
192
212
|
};
|
|
193
213
|
// Translate the parser's window-relative cursor to an absolute source
|
|
194
214
|
// cursor (windowStartFile advances as the window slides).
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
import fs from "fs";
|
|
10
10
|
import { describe, expect, test } from "@jest/globals";
|
|
11
11
|
import IfcStepParser from "../../ifc/ifc_step_parser.js";
|
|
12
|
-
import { BufferByteSource } from "./byte_source.js";
|
|
12
|
+
import { BufferByteSource, StoreByteSource } from "./byte_source.js";
|
|
13
|
+
import { InMemoryStepByteStore } from "../step_buffer_provider.js";
|
|
13
14
|
import { buildColumnarIndexStreaming, buildColumnarIndexStreamingAsync, } from "./streaming_index_builder.js";
|
|
14
15
|
import { ParseResult } from "./step_parser.js";
|
|
15
16
|
const POOL = 8 * 1024; // small window → forces slides on both inputs
|
|
@@ -53,6 +54,17 @@ describe("buildColumnarIndexStreamingAsync", () => {
|
|
|
53
54
|
expect(cooperative.stats.slides).toBe(sync.stats.slides);
|
|
54
55
|
expect(cooperative.stats.slides).toBeGreaterThan(0);
|
|
55
56
|
}, 60000);
|
|
57
|
+
test("StoreByteSource fills produce the same columns as a buffer source", async () => {
|
|
58
|
+
const bytes = new Uint8Array(fs.readFileSync("data/index.ifc"));
|
|
59
|
+
const parser = IfcStepParser.Instance;
|
|
60
|
+
const fromBuffer = await buildColumnarIndexStreamingAsync(new BufferByteSource(bytes), parser, POOL, void 0, void 0, 0);
|
|
61
|
+
const fromStore = await buildColumnarIndexStreamingAsync(new StoreByteSource(new InMemoryStepByteStore(bytes)), parser, POOL, void 0, void 0, 0);
|
|
62
|
+
expect(fromStore.result).toBe(ParseResult.COMPLETE);
|
|
63
|
+
expect(Array.from(fromStore.columns.address))
|
|
64
|
+
.toEqual(Array.from(fromBuffer.columns.address));
|
|
65
|
+
expect(Array.from(fromStore.columns.expressID))
|
|
66
|
+
.toEqual(Array.from(fromBuffer.columns.expressID));
|
|
67
|
+
}, 60000);
|
|
56
68
|
test("yields to the event loop and reports absolute progress mid-parse", async () => {
|
|
57
69
|
const bytes = syntheticIfc(10000);
|
|
58
70
|
const parser = IfcStepParser.Instance;
|
|
@@ -150,6 +150,21 @@ export interface StepBufferProvider {
|
|
|
150
150
|
* @return {Promise< void >} Resolves when resident.
|
|
151
151
|
*/
|
|
152
152
|
ensureResident(address: number, length: number): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Hold a range against LRU eviction until a matching
|
|
155
|
+
* {@link unpinRange}. No-op on a fully-resident source. Refcounted.
|
|
156
|
+
*
|
|
157
|
+
* @param address Absolute start of the range.
|
|
158
|
+
* @param length Length of the range.
|
|
159
|
+
*/
|
|
160
|
+
pinRange?(address: number, length: number): void;
|
|
161
|
+
/**
|
|
162
|
+
* Drop one {@link pinRange} hold on a range.
|
|
163
|
+
*
|
|
164
|
+
* @param address Absolute start of the range.
|
|
165
|
+
* @param length Length of the range.
|
|
166
|
+
*/
|
|
167
|
+
unpinRange?(address: number, length: number): void;
|
|
153
168
|
}
|
|
154
169
|
/**
|
|
155
170
|
* Provider over a fully-resident source buffer — the default, and
|
|
@@ -274,5 +289,34 @@ export declare class WindowedStepBufferProvider implements StepBufferProvider {
|
|
|
274
289
|
* @return {Promise< void >} Resolves when resident.
|
|
275
290
|
*/
|
|
276
291
|
ensureResident(address: number, length: number): Promise<void>;
|
|
292
|
+
/**
|
|
293
|
+
* Hold a range against LRU eviction until {@link unpinRange}.
|
|
294
|
+
*
|
|
295
|
+
* @param address Absolute start of the range.
|
|
296
|
+
* @param length Length of the range.
|
|
297
|
+
*/
|
|
298
|
+
pinRange(address: number, length: number): void;
|
|
299
|
+
/**
|
|
300
|
+
* Drop one {@link pinRange} hold.
|
|
301
|
+
*
|
|
302
|
+
* @param address Absolute start of the range.
|
|
303
|
+
* @param length Length of the range.
|
|
304
|
+
*/
|
|
305
|
+
unpinRange(address: number, length: number): void;
|
|
306
|
+
/**
|
|
307
|
+
* Chunk indices covering `[address, address + length)`.
|
|
308
|
+
*
|
|
309
|
+
* @param address Absolute start.
|
|
310
|
+
* @param length Length in bytes.
|
|
311
|
+
* @return {number[]} Inclusive chunk indices.
|
|
312
|
+
*/
|
|
313
|
+
private chunkSpan_;
|
|
314
|
+
/**
|
|
315
|
+
* Adjust a chunk's pin count, deleting the entry at zero.
|
|
316
|
+
*
|
|
317
|
+
* @param chunkIndex The chunk.
|
|
318
|
+
* @param delta +1 pin or -1 unpin.
|
|
319
|
+
*/
|
|
320
|
+
private addPin_;
|
|
277
321
|
}
|
|
278
322
|
//# sourceMappingURL=step_buffer_provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step_buffer_provider.d.ts","sourceRoot":"","sources":["../../../src/step/step_buffer_provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAqBH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAE,MAAM,EAAE,UAAU,GAAI,MAAM,CAE3D;AAmBD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IAEpC,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAE3B;;;;;;;OAOG;IACH,IAAI,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAI,OAAO,CAAE,UAAU,CAAE,CAAA;CAC9D;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,qBAAqB;IAOpD,OAAO,CAAC,QAAQ,CAAC,MAAM;IALpC;;;;OAIG;gBAC2B,MAAM,EAAE,UAAU;IAEhD;;;;OAIG;IACH,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED;;;;;;OAMG;IACI,IAAI,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAI,OAAO,CAAE,UAAU,CAAE;CAGrE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,UAAU,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;aAQtB,OAAO,EAAE,MAAM;aAAkB,MAAM,EAAE,MAAM;IAN5E;;;;;OAKG;gBAC0B,OAAO,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM;CAM7E;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAEjC,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAE3B,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B;;;;;;;OAOG;IACH,OAAO,CAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAI,qBAAqB,CAAA;IAEjE;;;;;;OAMG;IACH,cAAc,CAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAI,OAAO,CAAE,IAAI,CAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"step_buffer_provider.d.ts","sourceRoot":"","sources":["../../../src/step/step_buffer_provider.ts"],"names":[],"mappings":"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"}
|