@idfkit/core 0.0.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/LICENSE +21 -0
- package/README.md +120 -0
- package/dist/collection.d.ts +48 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +100 -0
- package/dist/collection.js.map +1 -0
- package/dist/document.d.ts +100 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +0 -0
- package/dist/document.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +25 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +25 -0
- package/dist/internal.js.map +1 -0
- package/dist/node.d.ts +40 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +70 -0
- package/dist/node.js.map +1 -0
- package/dist/object.d.ts +114 -0
- package/dist/object.d.ts.map +1 -0
- package/dist/object.js +224 -0
- package/dist/object.js.map +1 -0
- package/dist/parse/epjson.d.ts +16 -0
- package/dist/parse/epjson.d.ts.map +1 -0
- package/dist/parse/epjson.js +91 -0
- package/dist/parse/epjson.js.map +1 -0
- package/dist/parse/idf.d.ts +44 -0
- package/dist/parse/idf.d.ts.map +1 -0
- package/dist/parse/idf.js +170 -0
- package/dist/parse/idf.js.map +1 -0
- package/dist/parse/lexer.d.ts +37 -0
- package/dist/parse/lexer.d.ts.map +1 -0
- package/dist/parse/lexer.js +105 -0
- package/dist/parse/lexer.js.map +1 -0
- package/dist/references.d.ts +56 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +147 -0
- package/dist/references.js.map +1 -0
- package/dist/shape.d.ts +54 -0
- package/dist/shape.d.ts.map +1 -0
- package/dist/shape.js +114 -0
- package/dist/shape.js.map +1 -0
- package/dist/typemap.d.ts +43 -0
- package/dist/typemap.d.ts.map +1 -0
- package/dist/typemap.js +18 -0
- package/dist/typemap.js.map +1 -0
- package/dist/types/v26-1.d.ts +65896 -0
- package/dist/types/v26-1.d.ts.map +1 -0
- package/dist/types/v26-1.js +5 -0
- package/dist/types/v26-1.js.map +1 -0
- package/dist/types/v9-4.d.ts +61414 -0
- package/dist/types/v9-4.d.ts.map +1 -0
- package/dist/types/v9-4.js +5 -0
- package/dist/types/v9-4.js.map +1 -0
- package/dist/versions.d.ts +17 -0
- package/dist/versions.d.ts.map +1 -0
- package/dist/versions.js +34 -0
- package/dist/versions.js.map +1 -0
- package/dist/write/epjson.d.ts +15 -0
- package/dist/write/epjson.d.ts.map +1 -0
- package/dist/write/epjson.js +10 -0
- package/dist/write/epjson.js.map +1 -0
- package/dist/write/idf.d.ts +47 -0
- package/dist/write/idf.d.ts.map +1 -0
- package/dist/write/idf.js +149 -0
- package/dist/write/idf.js.map +1 -0
- package/package.json +55 -0
package/dist/shape.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { DATA, OWNER, SHAPE } from './internal.js';
|
|
2
|
+
/**
|
|
3
|
+
* Per-object-type prototype carrying real accessors for every field.
|
|
4
|
+
*
|
|
5
|
+
* The Python library resolves `zone.ceiling_height` through `__getattr__`. The
|
|
6
|
+
* mechanical translation of that is a `Proxy`, which we deliberately do not use:
|
|
7
|
+
* proxies defeat V8's inline caches, and more importantly they are invisible to
|
|
8
|
+
* TypeScript, so nothing would autocomplete. Instead each object type gets one
|
|
9
|
+
* prototype with `Object.defineProperty` accessors, built once and shared by
|
|
10
|
+
* every instance of that type. Property access is then an ordinary monomorphic
|
|
11
|
+
* lookup, and the generated `.d.ts` interfaces describe it statically.
|
|
12
|
+
*
|
|
13
|
+
* Shapes are keyed by the schema definition object rather than by type name.
|
|
14
|
+
* Because the schema bundle is content-addressed, `Zone` in 9.4.0 and `Zone` in
|
|
15
|
+
* 26.1.0 are the same frozen definition, so they share one shape and one
|
|
16
|
+
* prototype. Cross-version documents stay monomorphic for free.
|
|
17
|
+
*/
|
|
18
|
+
export class ObjectShape {
|
|
19
|
+
typeName;
|
|
20
|
+
type;
|
|
21
|
+
proto;
|
|
22
|
+
/** Field names in IDF positional order, excluding the name field. */
|
|
23
|
+
fields;
|
|
24
|
+
/** Fields that point into a reference list, i.e. foreign keys. */
|
|
25
|
+
refFields;
|
|
26
|
+
/**
|
|
27
|
+
* Fields *inside* the extensible group that point into a reference list.
|
|
28
|
+
*
|
|
29
|
+
* Kept separate from `refFields` because these live in `type.x.fields`, not
|
|
30
|
+
* the positional field list, and so need the repeat index to address them.
|
|
31
|
+
* Ignoring them is not cosmetic: `ZoneList`, `Branch`, and the supply/return
|
|
32
|
+
* paths carry all of their references here, so leaving them out of the graph
|
|
33
|
+
* makes `rename()` silently produce a broken model.
|
|
34
|
+
*/
|
|
35
|
+
extensibleRefFields;
|
|
36
|
+
/** Fields whose value declares a name other objects may reference. */
|
|
37
|
+
keyFields;
|
|
38
|
+
/** Extensible array key (`vertices`), if this type has one. */
|
|
39
|
+
extensibleKey;
|
|
40
|
+
/** Whether the object carries a name (most do; `Version` does not). */
|
|
41
|
+
named;
|
|
42
|
+
constructor(typeName, type, base) {
|
|
43
|
+
this.typeName = typeName;
|
|
44
|
+
this.type = type;
|
|
45
|
+
this.named = type.anon !== 1;
|
|
46
|
+
const fields = type.f.filter((f) => f !== 'name');
|
|
47
|
+
this.fields = fields;
|
|
48
|
+
this.extensibleKey = type.x?.key;
|
|
49
|
+
this.refFields = fields.filter((f) => (type.p[f]?.ol?.length ?? 0) > 0);
|
|
50
|
+
this.keyFields = fields.filter((f) => (type.p[f]?.ref?.length ?? 0) > 0);
|
|
51
|
+
const extensible = type.x;
|
|
52
|
+
this.extensibleRefFields =
|
|
53
|
+
extensible === undefined
|
|
54
|
+
? []
|
|
55
|
+
: extensible.fields.filter((f) => (extensible.p[f]?.ol?.length ?? 0) > 0);
|
|
56
|
+
const proto = Object.create(base);
|
|
57
|
+
for (const field of fields) {
|
|
58
|
+
defineFieldAccessor(proto, field);
|
|
59
|
+
}
|
|
60
|
+
// The extensible array lives under its own epJSON key (`vertices`) rather
|
|
61
|
+
// than in the positional field list, so it needs an accessor of its own.
|
|
62
|
+
if (this.extensibleKey !== undefined && !fields.includes(this.extensibleKey)) {
|
|
63
|
+
defineFieldAccessor(proto, this.extensibleKey);
|
|
64
|
+
}
|
|
65
|
+
this.proto = Object.freeze(proto);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function defineFieldAccessor(proto, field) {
|
|
69
|
+
Object.defineProperty(proto, field, {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
configurable: false,
|
|
72
|
+
get() {
|
|
73
|
+
return this[DATA][field];
|
|
74
|
+
},
|
|
75
|
+
set(value) {
|
|
76
|
+
const previous = this[DATA][field];
|
|
77
|
+
if (previous === value)
|
|
78
|
+
return;
|
|
79
|
+
if (value === undefined || value === null)
|
|
80
|
+
delete this[DATA][field];
|
|
81
|
+
else
|
|
82
|
+
this[DATA][field] = value;
|
|
83
|
+
// The document keeps the reference graph live. Routing writes through a
|
|
84
|
+
// real setter is what lets us do that without a Proxy and without asking
|
|
85
|
+
// callers to mutate via an explicit `update()` call.
|
|
86
|
+
this[OWNER]?.onFieldChanged(this, field, previous, value);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const shapeCache = new WeakMap();
|
|
91
|
+
/**
|
|
92
|
+
* Get (or build) the shape for an object type.
|
|
93
|
+
*
|
|
94
|
+
* `base` is `IdfObject.prototype`, threaded in rather than imported to keep
|
|
95
|
+
* this module free of a cycle with `object.ts`.
|
|
96
|
+
*/
|
|
97
|
+
export function shapeFor(typeName, type, base) {
|
|
98
|
+
let byName = shapeCache.get(type);
|
|
99
|
+
if (byName === undefined) {
|
|
100
|
+
byName = new Map();
|
|
101
|
+
shapeCache.set(type, byName);
|
|
102
|
+
}
|
|
103
|
+
let shape = byName.get(typeName);
|
|
104
|
+
if (shape === undefined) {
|
|
105
|
+
shape = new ObjectShape(typeName, type, base);
|
|
106
|
+
byName.set(typeName, shape);
|
|
107
|
+
}
|
|
108
|
+
return shape;
|
|
109
|
+
}
|
|
110
|
+
/** Number of distinct shapes built, for tests and diagnostics. */
|
|
111
|
+
export function shapeOf(obj) {
|
|
112
|
+
return obj[SHAPE];
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shape.js","sourceRoot":"","sources":["../src/shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version-specific static typing, with no runtime cost at all.
|
|
3
|
+
*
|
|
4
|
+
* A generated module (`@idfkit/core/types/v26-1`) exports one interface per
|
|
5
|
+
* object type plus a `TypeMap` joining type name to interface. A document
|
|
6
|
+
* parameterized by that map resolves `doc.all('Zone')` to a collection of
|
|
7
|
+
* objects with `Zone`'s fields, and the editor completes among all 858 type
|
|
8
|
+
* names as you type the string.
|
|
9
|
+
*
|
|
10
|
+
* This is where JavaScript beats the Python original rather than imitating it.
|
|
11
|
+
* `__getattr__` resolves names at runtime, so an editor cannot see them and a
|
|
12
|
+
* typo surfaces as `None` at simulation time. Here the schema is compiled into
|
|
13
|
+
* the type system, so `doc.all('Zone').first.celing_height` is a compile error,
|
|
14
|
+
* and none of it exists once the code is running: the maps are types, erased at
|
|
15
|
+
* build time, and the argument really is just a string.
|
|
16
|
+
*/
|
|
17
|
+
import type { FieldValues } from './object.js';
|
|
18
|
+
/** Base constraint: any map from object type name to its field interface. */
|
|
19
|
+
export type AnyTypeMap = Record<string, object>;
|
|
20
|
+
/** A document with no version types attached. */
|
|
21
|
+
export type UntypedMap = Record<never, never>;
|
|
22
|
+
/**
|
|
23
|
+
* Accepted type names for a map.
|
|
24
|
+
*
|
|
25
|
+
* The `string & {}` arm is what keeps literal completion alive while still
|
|
26
|
+
* accepting arbitrary strings: without it TypeScript widens the parameter to
|
|
27
|
+
* `string` and the suggestions disappear.
|
|
28
|
+
*/
|
|
29
|
+
export type TypeNameOf<M extends AnyTypeMap> = (keyof M & string) | (string & {});
|
|
30
|
+
/** Field interface for a type name, or an empty object for unknown names. */
|
|
31
|
+
export type ObjectOf<M extends AnyTypeMap, K extends string> = K extends keyof M ? M[K] : UntypedMap;
|
|
32
|
+
/**
|
|
33
|
+
* Field values accepted when creating an object of a given type.
|
|
34
|
+
*
|
|
35
|
+
* Deliberately not `ObjectOf`. For a known type name this is the exact field
|
|
36
|
+
* interface, so TypeScript's excess-property check rejects a misspelled field
|
|
37
|
+
* in an object literal. For anything else it widens to the permissive
|
|
38
|
+
* `FieldValues`, which is what version-generic code and untyped documents need.
|
|
39
|
+
* Using one type for both would force a choice between catching typos and
|
|
40
|
+
* allowing dynamic field names; using two costs nothing and gives both.
|
|
41
|
+
*/
|
|
42
|
+
export type ValuesOf<M extends AnyTypeMap, K extends string> = K extends keyof M ? Partial<M[K]> : FieldValues;
|
|
43
|
+
//# sourceMappingURL=typemap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typemap.d.ts","sourceRoot":"","sources":["../src/typemap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,UAAU,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElF,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,CAAC,GAC5E,CAAC,CAAC,CAAC,CAAC,GACJ,UAAU,CAAC;AAEf;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,CAAC,GAC5E,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACb,WAAW,CAAC"}
|
package/dist/typemap.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version-specific static typing, with no runtime cost at all.
|
|
3
|
+
*
|
|
4
|
+
* A generated module (`@idfkit/core/types/v26-1`) exports one interface per
|
|
5
|
+
* object type plus a `TypeMap` joining type name to interface. A document
|
|
6
|
+
* parameterized by that map resolves `doc.all('Zone')` to a collection of
|
|
7
|
+
* objects with `Zone`'s fields, and the editor completes among all 858 type
|
|
8
|
+
* names as you type the string.
|
|
9
|
+
*
|
|
10
|
+
* This is where JavaScript beats the Python original rather than imitating it.
|
|
11
|
+
* `__getattr__` resolves names at runtime, so an editor cannot see them and a
|
|
12
|
+
* typo surfaces as `None` at simulation time. Here the schema is compiled into
|
|
13
|
+
* the type system, so `doc.all('Zone').first.celing_height` is a compile error,
|
|
14
|
+
* and none of it exists once the code is running: the maps are types, erased at
|
|
15
|
+
* build time, and the argument really is just a string.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=typemap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typemap.js","sourceRoot":"","sources":["../src/typemap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|