layout-data 0.0.0-stage → 0.2.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.
- package/CHANGELOG.md +35 -0
- package/LICENSE +373 -0
- package/README.md +125 -2
- package/dist/layout-data.js +8320 -0
- package/dist/types/Ldata.d.ts +169 -0
- package/dist/types/Ltag.d.ts +74 -0
- package/dist/types/codecs.d.ts +11 -0
- package/dist/types/dispatch.d.ts +11 -0
- package/dist/types/endian.d.ts +65 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/internal_types.d.ts +65 -0
- package/dist/types/layout.d.ts +54 -0
- package/dist/types/observer.d.ts +43 -0
- package/dist/types/registry.d.ts +47 -0
- package/dist/types/reserved.d.ts +9 -0
- package/dist/types/structure.d.ts +27 -0
- package/dist/types/typedefs.d.ts +155 -0
- package/dist/types/types.d.ts +25 -0
- package/package.json +47 -3
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An entry of a layout description that defines a tag (doc/spec-data-api.md §6.2).
|
|
3
|
+
*/
|
|
4
|
+
export type Tag_Item = {
|
|
5
|
+
/**
|
|
6
|
+
* - Tag name.
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
/**
|
|
10
|
+
* - Tag type, case-insensitive (see Tag_Type).
|
|
11
|
+
*/
|
|
12
|
+
type: string;
|
|
13
|
+
/**
|
|
14
|
+
* - Bit offset, relative to the parent entry until expanded.
|
|
15
|
+
*/
|
|
16
|
+
offset: number;
|
|
17
|
+
/**
|
|
18
|
+
* - Length in bits, filled in from the type when omitted.
|
|
19
|
+
*/
|
|
20
|
+
length?: number;
|
|
21
|
+
/**
|
|
22
|
+
* - Initial value.
|
|
23
|
+
*/
|
|
24
|
+
init_value?: number | boolean;
|
|
25
|
+
/**
|
|
26
|
+
* - Description, rendered into the generated types.
|
|
27
|
+
*/
|
|
28
|
+
comment?: string;
|
|
29
|
+
/**
|
|
30
|
+
* - Descriptive mark of a combined word; the linkage is decided by `coupling`.
|
|
31
|
+
*/
|
|
32
|
+
is_combined?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* - The bits of a combined word, as an inline list or the name of a fragment.
|
|
35
|
+
*/
|
|
36
|
+
coupling?: Tag_Item[] | string;
|
|
37
|
+
/**
|
|
38
|
+
* - A tag entry does not include entries.
|
|
39
|
+
*/
|
|
40
|
+
includes?: never;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* An entry of a layout description that splices in other entries (doc/spec-data-api.md §6.2).
|
|
44
|
+
*/
|
|
45
|
+
export type Include_Item = {
|
|
46
|
+
/**
|
|
47
|
+
* - The entries to include, as an inline list or the name of a fragment.
|
|
48
|
+
*/
|
|
49
|
+
includes: Layout_Item[] | string;
|
|
50
|
+
/**
|
|
51
|
+
* - Bit offset by which the included entries are shifted as a whole.
|
|
52
|
+
*/
|
|
53
|
+
offset: number;
|
|
54
|
+
/**
|
|
55
|
+
* - Prefix of the names of the included entries.
|
|
56
|
+
*/
|
|
57
|
+
name_prefix?: string;
|
|
58
|
+
/**
|
|
59
|
+
* - An inclusion defines no tag.
|
|
60
|
+
*/
|
|
61
|
+
name?: never;
|
|
62
|
+
/**
|
|
63
|
+
* - An inclusion defines no tag.
|
|
64
|
+
*/
|
|
65
|
+
type?: never;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* One entry of a layout description, as written by the user in a layout file
|
|
69
|
+
* or given to register_layout (doc/spec-data-api.md §6).
|
|
70
|
+
*/
|
|
71
|
+
export type Layout_Item = Tag_Item | Include_Item;
|
|
72
|
+
/**
|
|
73
|
+
* A layout description: `layouts` maps layout names to lists of entries, and
|
|
74
|
+
* every other key is a fragment, a list of entries that can be named
|
|
75
|
+
* (doc/spec-data-api.md §6.1).
|
|
76
|
+
*/
|
|
77
|
+
export type Layout_Description = {
|
|
78
|
+
layouts?: Record<string, Layout_Item[]>;
|
|
79
|
+
} & Record<string, Layout_Item[] | Record<string, Layout_Item[]> | undefined>;
|
|
80
|
+
/**
|
|
81
|
+
* One tag of a compiled layout (doc/spec-data-api.md §6.6), read-only:
|
|
82
|
+
* `name`; `type`, as written in the description; `offset`, the absolute bit
|
|
83
|
+
* offset; `length` in bits; `init_value`; `comment`, if given; `coupling`,
|
|
84
|
+
* the tag names of the bits of a combined word, or of the combined words a
|
|
85
|
+
* bit belongs to.
|
|
86
|
+
*/
|
|
87
|
+
export type Layout_Tag = Readonly<{
|
|
88
|
+
name: string;
|
|
89
|
+
type: string;
|
|
90
|
+
offset: number;
|
|
91
|
+
length: number;
|
|
92
|
+
init_value: number | boolean;
|
|
93
|
+
comment?: string;
|
|
94
|
+
coupling: readonly string[];
|
|
95
|
+
}>;
|
|
96
|
+
/**
|
|
97
|
+
* A compiled layout (doc/spec-data-api.md §6.6), read-only and deeply frozen:
|
|
98
|
+
* `name`; `length` in bits; `size` in bytes; `items`, the tags in layout
|
|
99
|
+
* order (a combined word before its bits).
|
|
100
|
+
*/
|
|
101
|
+
export type Layout = Readonly<{
|
|
102
|
+
name: string;
|
|
103
|
+
length: number;
|
|
104
|
+
size: number;
|
|
105
|
+
items: readonly Layout_Tag[];
|
|
106
|
+
}>;
|
|
107
|
+
/**
|
|
108
|
+
* Device byte order of an IO buffer (doc/spec-data-api.md §2.9).
|
|
109
|
+
*/
|
|
110
|
+
export type Endian = "BE" | "LE" | "BEBS" | "LEBS";
|
|
111
|
+
/**
|
|
112
|
+
* A source of layouts: the path of a YAML 1.2 layout file, or a description
|
|
113
|
+
* that is already parsed (the same structure as the file, doc/spec-data-api.md §6.1).
|
|
114
|
+
*/
|
|
115
|
+
export type Layout_Source = string | Layout_Description;
|
|
116
|
+
/**
|
|
117
|
+
* The result of registering a layout description.
|
|
118
|
+
*/
|
|
119
|
+
export type Registered_Layouts = {
|
|
120
|
+
layouts: Record<string, Layout>;
|
|
121
|
+
fragments: Record<string, Layout_Item[]>;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Type of a tag, in lower case: the type of `Ltag.type` (doc/spec-data-api.md §1).
|
|
125
|
+
*/
|
|
126
|
+
export type Tag_Type = "bool" | "byte" | "usint" | "sint" | "int" | "uint" | "word" | "dint" | "udint" | "dword" | "real";
|
|
127
|
+
/**
|
|
128
|
+
* The listeners of the events of an Ldata that the library emits.
|
|
129
|
+
*/
|
|
130
|
+
export type Data_Events = {
|
|
131
|
+
change: (name: string, old_value: number | boolean, new_value: number | boolean) => void;
|
|
132
|
+
write: (data: import("./Ldata.js").Ldata) => void;
|
|
133
|
+
access: (kind: "read" | "write", tags: import("./Ltag.js").Ltag[]) => void;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* A class-level access listener: called for the accesses to every Ldata
|
|
137
|
+
* (doc/spec-data-api.md §2.8).
|
|
138
|
+
*/
|
|
139
|
+
export type Class_Access_Listener = (data: import("./Ldata.js").Ldata, kind: "read" | "write", tags: import("./Ltag.js").Ltag[]) => void;
|
|
140
|
+
/**
|
|
141
|
+
* The listener of an event of an Ldata: typed for `change` and `write`, any
|
|
142
|
+
* listener for another name (doc/spec-data-api.md §2.7).
|
|
143
|
+
*/
|
|
144
|
+
export type Data_Listener<E extends string | symbol> = E extends keyof Data_Events ? Data_Events[E] : (...args: any[]) => void;
|
|
145
|
+
/**
|
|
146
|
+
* The listeners of the events of an Ltag that the library emits.
|
|
147
|
+
*/
|
|
148
|
+
export type Tag_Events = {
|
|
149
|
+
change: (old_value: number | boolean, new_value: number | boolean) => void;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* The listener of an event of an Ltag: typed for `change`, any listener for
|
|
153
|
+
* another name (doc/spec-data-api.md §3).
|
|
154
|
+
*/
|
|
155
|
+
export type Tag_Listener<E extends string | symbol> = E extends keyof Tag_Events ? Tag_Events[E] : (...args: any[]) => void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a declaration file with, for each layout, an interface of its tags
|
|
3
|
+
* (`<Layout>_Tags`, one property per tag) and the type of its data block
|
|
4
|
+
* (`<Layout>_Ldata`). The layout name is used as it is, with the case it has,
|
|
5
|
+
* so that the type names are those of `new Ldata("<Layout>", ...)` and layouts
|
|
6
|
+
* with different names never get the same type name.
|
|
7
|
+
*
|
|
8
|
+
* In JavaScript a JSDoc cast names the type of the value, which an editor
|
|
9
|
+
* uses for completion and, with `checkJs`, to check the tags:
|
|
10
|
+
*
|
|
11
|
+
* ```js
|
|
12
|
+
* const pump = /** @type {import("./layout_types.js").Pump_Ldata} *\/ (new Ldata("Pump", "pump_1"));
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @param {Record<string, import("./typedefs.js").Layout>} layouts - Registered layouts by name.
|
|
16
|
+
* @param {object} [options]
|
|
17
|
+
* @param {string} [options.source] - The layout file, named in the header; the header names none when it is omitted.
|
|
18
|
+
* @param {string} [options.ldata_module] - Module specifier of Ldata, relative to the output file; "layout-data" by default.
|
|
19
|
+
* @returns {string}
|
|
20
|
+
* @throws {Error} With `errors`, when the name of a layout is not an identifier, which a type name needs.
|
|
21
|
+
*/
|
|
22
|
+
export function render_types(layouts: Record<string, import("./typedefs.js").Layout>, { source, ldata_module }?: {
|
|
23
|
+
source?: string;
|
|
24
|
+
ldata_module?: string;
|
|
25
|
+
}): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "layout-data",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Structured, reactive, buffer-based data blocks with named, typed tags",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/types/index.d.ts",
|
|
9
|
+
"default": "./dist/layout-data.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"CHANGELOG.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20.11"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@eslint/js": "10.0.1",
|
|
21
|
+
"@stylistic/eslint-plugin": "5.10.0",
|
|
22
|
+
"@types/node": "^20.19.43",
|
|
23
|
+
"eslint": "10.12.0",
|
|
24
|
+
"globals": "17.13.0",
|
|
25
|
+
"rolldown": "^1.2.12",
|
|
26
|
+
"typescript": "^5.9.3",
|
|
27
|
+
"yaml": "^2.9.1"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"buffer",
|
|
31
|
+
"struct",
|
|
32
|
+
"tag",
|
|
33
|
+
"PLC",
|
|
34
|
+
"layout"
|
|
35
|
+
],
|
|
36
|
+
"author": "Goosy Jo <goosy.jo@gmail.com>",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/goosy/data_block.git"
|
|
40
|
+
},
|
|
41
|
+
"license": "MPL-2.0",
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "rolldown -c",
|
|
44
|
+
"typecheck": "tsc -p tsconfig.json --noEmit false --emitDeclarationOnly --outDir .local/types",
|
|
45
|
+
"test": "pnpm build && pnpm test:types && node --test",
|
|
46
|
+
"test:types": "tsc -p type_check",
|
|
47
|
+
"lint": "eslint .",
|
|
48
|
+
"bench": "node bench/change_detection_bench.js"
|
|
49
|
+
}
|
|
6
50
|
}
|