@highstate/cli 0.9.15 → 0.9.16
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/dist/highstate.manifest.json +1 -1
- package/dist/library-loader-CGEPTS4L.js +78 -0
- package/dist/library-loader-CGEPTS4L.js.map +1 -0
- package/dist/main.js +257 -1096
- package/dist/main.js.map +1 -1
- package/package.json +27 -6
- package/src/commands/backend/identity.ts +24 -0
- package/src/commands/build.ts +41 -5
- package/src/main.ts +2 -0
- package/src/shared/index.ts +1 -0
- package/src/shared/library-loader.ts +113 -0
- package/src/shared/schema-transformer.spec.ts +209 -0
- package/src/shared/schema-transformer.ts +112 -11
- package/src/shared/schemas.ts +41 -0
- package/src/shared/source-hash-calculator.ts +129 -26
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/shared/library-loader.ts
|
|
2
|
+
import {
|
|
3
|
+
isComponent,
|
|
4
|
+
isEntity,
|
|
5
|
+
isUnitModel,
|
|
6
|
+
originalCreate
|
|
7
|
+
} from "@highstate/contract";
|
|
8
|
+
import { serializeFunction } from "@pulumi/pulumi/runtime/index.js";
|
|
9
|
+
import { Crc32, crc32 } from "@aws-crypto/crc32";
|
|
10
|
+
import { encode } from "@msgpack/msgpack";
|
|
11
|
+
import { int32ToBytes } from "@highstate/backend/shared";
|
|
12
|
+
async function loadLibrary(logger, modulePaths) {
|
|
13
|
+
const modules = {};
|
|
14
|
+
for (const modulePath of modulePaths) {
|
|
15
|
+
try {
|
|
16
|
+
logger.debug({ modulePath }, "loading module");
|
|
17
|
+
modules[modulePath] = await import(modulePath);
|
|
18
|
+
logger.debug({ modulePath }, "module loaded");
|
|
19
|
+
} catch (err) {
|
|
20
|
+
logger.error({ modulePath, err }, "module load failed");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const components = {};
|
|
24
|
+
const entities = {};
|
|
25
|
+
await _loadLibrary(modules, components, entities);
|
|
26
|
+
logger.info(
|
|
27
|
+
{
|
|
28
|
+
componentCount: Object.keys(components).length,
|
|
29
|
+
entityCount: Object.keys(entities).length
|
|
30
|
+
},
|
|
31
|
+
"library loaded"
|
|
32
|
+
);
|
|
33
|
+
logger.trace({ components, entities }, "library content");
|
|
34
|
+
return { components, entities };
|
|
35
|
+
}
|
|
36
|
+
async function _loadLibrary(value, components, entities) {
|
|
37
|
+
if (isComponent(value)) {
|
|
38
|
+
const entityHashes = [];
|
|
39
|
+
for (const entity of value.entities.values()) {
|
|
40
|
+
entity.definitionHash ??= calculateEntityDefinitionHash(entity);
|
|
41
|
+
entityHashes.push(entity.definitionHash);
|
|
42
|
+
}
|
|
43
|
+
components[value.model.type] = value.model;
|
|
44
|
+
value.model.definitionHash = await calculateComponentDefinitionHash(value, entityHashes);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (isEntity(value)) {
|
|
48
|
+
entities[value.type] = value;
|
|
49
|
+
entities[value.type].definitionHash ??= calculateEntityDefinitionHash(value);
|
|
50
|
+
delete value.schema;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (typeof value !== "object" || value === null) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
for (const key in value) {
|
|
57
|
+
await _loadLibrary(value[key], components, entities);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function calculateComponentDefinitionHash(component, entityHashes) {
|
|
61
|
+
const result = new Crc32();
|
|
62
|
+
result.update(encode(component.model));
|
|
63
|
+
if (!isUnitModel(component.model)) {
|
|
64
|
+
const serializedCreate = await serializeFunction(component[originalCreate]);
|
|
65
|
+
result.update(Buffer.from(serializedCreate.text));
|
|
66
|
+
}
|
|
67
|
+
for (const entityHash of entityHashes) {
|
|
68
|
+
result.update(int32ToBytes(entityHash));
|
|
69
|
+
}
|
|
70
|
+
return result.digest();
|
|
71
|
+
}
|
|
72
|
+
function calculateEntityDefinitionHash(entity) {
|
|
73
|
+
return crc32(encode(entity));
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
loadLibrary
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=library-loader-CGEPTS4L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/library-loader.ts"],"sourcesContent":["import type { Logger } from \"pino\"\nimport {\n type Component,\n type ComponentModel,\n type Entity,\n isComponent,\n isEntity,\n isUnitModel,\n originalCreate,\n} from \"@highstate/contract\"\nimport { serializeFunction } from \"@pulumi/pulumi/runtime/index.js\"\nimport { Crc32, crc32 } from \"@aws-crypto/crc32\"\nimport { encode } from \"@msgpack/msgpack\"\nimport { int32ToBytes } from \"@highstate/backend/shared\"\n\nexport type Library = Readonly<{\n components: Readonly<Record<string, ComponentModel>>\n entities: Readonly<Record<string, Entity>>\n}>\n\nexport async function loadLibrary(logger: Logger, modulePaths: string[]): Promise<Library> {\n const modules: Record<string, unknown> = {}\n for (const modulePath of modulePaths) {\n try {\n logger.debug({ modulePath }, \"loading module\")\n modules[modulePath] = await import(modulePath)\n\n logger.debug({ modulePath }, \"module loaded\")\n } catch (err) {\n logger.error({ modulePath, err }, \"module load failed\")\n }\n }\n\n const components: Record<string, ComponentModel> = {}\n const entities: Record<string, Entity> = {}\n\n await _loadLibrary(modules, components, entities)\n\n logger.info(\n {\n componentCount: Object.keys(components).length,\n entityCount: Object.keys(entities).length,\n },\n \"library loaded\",\n )\n\n logger.trace({ components, entities }, \"library content\")\n\n return { components, entities }\n}\n\nasync function _loadLibrary(\n value: unknown,\n components: Record<string, ComponentModel>,\n entities: Record<string, Entity>,\n): Promise<void> {\n if (isComponent(value)) {\n const entityHashes: number[] = []\n for (const entity of value.entities.values()) {\n entity.definitionHash ??= calculateEntityDefinitionHash(entity)\n entityHashes.push(entity.definitionHash)\n }\n\n components[value.model.type] = value.model\n value.model.definitionHash = await calculateComponentDefinitionHash(value, entityHashes)\n\n return\n }\n\n if (isEntity(value)) {\n entities[value.type] = value\n entities[value.type].definitionHash ??= calculateEntityDefinitionHash(value)\n\n // @ts-expect-error remove the schema since it's not needed in the designer\n delete value.schema\n return\n }\n\n if (typeof value !== \"object\" || value === null) {\n return\n }\n\n for (const key in value) {\n await _loadLibrary((value as Record<string, unknown>)[key], components, entities)\n }\n}\n\nasync function calculateComponentDefinitionHash(\n component: Component,\n entityHashes: number[],\n): Promise<number> {\n const result = new Crc32()\n\n // 1. include the full component model\n result.update(encode(component.model))\n\n if (!isUnitModel(component.model)) {\n // 2. for composite components, include the content of the serialized create function\n const serializedCreate = await serializeFunction(component[originalCreate])\n result.update(Buffer.from(serializedCreate.text))\n }\n\n // 3. include the hashes of all entities\n for (const entityHash of entityHashes) {\n result.update(int32ToBytes(entityHash))\n }\n\n return result.digest()\n}\n\nfunction calculateEntityDefinitionHash(entity: Entity): number {\n return crc32(encode(entity))\n}\n"],"mappings":";AACA;AAAA,EAIE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAClC,SAAS,OAAO,aAAa;AAC7B,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAO7B,eAAsB,YAAY,QAAgB,aAAyC;AACzF,QAAM,UAAmC,CAAC;AAC1C,aAAW,cAAc,aAAa;AACpC,QAAI;AACF,aAAO,MAAM,EAAE,WAAW,GAAG,gBAAgB;AAC7C,cAAQ,UAAU,IAAI,MAAM,OAAO;AAEnC,aAAO,MAAM,EAAE,WAAW,GAAG,eAAe;AAAA,IAC9C,SAAS,KAAK;AACZ,aAAO,MAAM,EAAE,YAAY,IAAI,GAAG,oBAAoB;AAAA,IACxD;AAAA,EACF;AAEA,QAAM,aAA6C,CAAC;AACpD,QAAM,WAAmC,CAAC;AAE1C,QAAM,aAAa,SAAS,YAAY,QAAQ;AAEhD,SAAO;AAAA,IACL;AAAA,MACE,gBAAgB,OAAO,KAAK,UAAU,EAAE;AAAA,MACxC,aAAa,OAAO,KAAK,QAAQ,EAAE;AAAA,IACrC;AAAA,IACA;AAAA,EACF;AAEA,SAAO,MAAM,EAAE,YAAY,SAAS,GAAG,iBAAiB;AAExD,SAAO,EAAE,YAAY,SAAS;AAChC;AAEA,eAAe,aACb,OACA,YACA,UACe;AACf,MAAI,YAAY,KAAK,GAAG;AACtB,UAAM,eAAyB,CAAC;AAChC,eAAW,UAAU,MAAM,SAAS,OAAO,GAAG;AAC5C,aAAO,mBAAmB,8BAA8B,MAAM;AAC9D,mBAAa,KAAK,OAAO,cAAc;AAAA,IACzC;AAEA,eAAW,MAAM,MAAM,IAAI,IAAI,MAAM;AACrC,UAAM,MAAM,iBAAiB,MAAM,iCAAiC,OAAO,YAAY;AAEvF;AAAA,EACF;AAEA,MAAI,SAAS,KAAK,GAAG;AACnB,aAAS,MAAM,IAAI,IAAI;AACvB,aAAS,MAAM,IAAI,EAAE,mBAAmB,8BAA8B,KAAK;AAG3E,WAAO,MAAM;AACb;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C;AAAA,EACF;AAEA,aAAW,OAAO,OAAO;AACvB,UAAM,aAAc,MAAkC,GAAG,GAAG,YAAY,QAAQ;AAAA,EAClF;AACF;AAEA,eAAe,iCACb,WACA,cACiB;AACjB,QAAM,SAAS,IAAI,MAAM;AAGzB,SAAO,OAAO,OAAO,UAAU,KAAK,CAAC;AAErC,MAAI,CAAC,YAAY,UAAU,KAAK,GAAG;AAEjC,UAAM,mBAAmB,MAAM,kBAAkB,UAAU,cAAc,CAAC;AAC1E,WAAO,OAAO,OAAO,KAAK,iBAAiB,IAAI,CAAC;AAAA,EAClD;AAGA,aAAW,cAAc,cAAc;AACrC,WAAO,OAAO,aAAa,UAAU,CAAC;AAAA,EACxC;AAEA,SAAO,OAAO,OAAO;AACvB;AAEA,SAAS,8BAA8B,QAAwB;AAC7D,SAAO,MAAM,OAAO,MAAM,CAAC;AAC7B;","names":[]}
|