@mermanjs/node 0.8.0-alpha.5

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE-APACHE +201 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +11 -0
  5. package/THIRD_PARTY_LICENSES/beautiful-mermaid/LICENSE +21 -0
  6. package/THIRD_PARTY_LICENSES/cose-base-v1/LICENSE +21 -0
  7. package/THIRD_PARTY_LICENSES/cose-base-v2/LICENSE +21 -0
  8. package/THIRD_PARTY_LICENSES/cytoscape/LICENSE +19 -0
  9. package/THIRD_PARTY_LICENSES/cytoscape-cose-bilkent/LICENSE +21 -0
  10. package/THIRD_PARTY_LICENSES/cytoscape-fcose/LICENSE +19 -0
  11. package/THIRD_PARTY_LICENSES/d3-shape/LICENSE +13 -0
  12. package/THIRD_PARTY_LICENSES/dagre/LICENSE +19 -0
  13. package/THIRD_PARTY_LICENSES/dompurify/LICENSE +202 -0
  14. package/THIRD_PARTY_LICENSES/eclipse-elk/LICENSE.md +264 -0
  15. package/THIRD_PARTY_LICENSES/elkjs/LICENSE.md +264 -0
  16. package/THIRD_PARTY_LICENSES/fmin/LICENSE +27 -0
  17. package/THIRD_PARTY_LICENSES/graphlib/LICENSE +19 -0
  18. package/THIRD_PARTY_LICENSES/katex-fonts/FONT_NOTICE.txt +12 -0
  19. package/THIRD_PARTY_LICENSES/katex-fonts/OFL.txt +85 -0
  20. package/THIRD_PARTY_LICENSES/layout-base-v1/LICENSE +21 -0
  21. package/THIRD_PARTY_LICENSES/layout-base-v2/LICENSE +21 -0
  22. package/THIRD_PARTY_LICENSES/mermaid/LICENSE +21 -0
  23. package/THIRD_PARTY_LICENSES/mermaid-ascii/LICENSE +21 -0
  24. package/THIRD_PARTY_LICENSES/mermaid-rs-renderer/LICENSE +21 -0
  25. package/THIRD_PARTY_LICENSES/ratex/LICENSE +27 -0
  26. package/THIRD_PARTY_LICENSES/ratex/THIRD_PARTY_NOTICES.txt +19 -0
  27. package/THIRD_PARTY_LICENSES/rough-rs/LICENSE +21 -0
  28. package/THIRD_PARTY_LICENSES/roughjs/LICENSE +21 -0
  29. package/THIRD_PARTY_LICENSES/rust-cargo-dependencies.json +5562 -0
  30. package/THIRD_PARTY_LICENSES/sanitize-url/LICENSE +21 -0
  31. package/THIRD_PARTY_LICENSES/venn-js/LICENSE +22 -0
  32. package/THIRD_PARTY_LICENSES/wasm-minimal-protocol/LICENSE +24 -0
  33. package/THIRD_PARTY_LICENSES/zenuml-core/LICENSE +21 -0
  34. package/THIRD_PARTY_NOTICES.md +524 -0
  35. package/dist/bounded-executor.mjs +132 -0
  36. package/dist/candidates/native.mjs +51 -0
  37. package/dist/candidates/wrap-engine.mjs +28 -0
  38. package/dist/engine.mjs +1255 -0
  39. package/dist/errors.mjs +1199 -0
  40. package/dist/generated/binding-contract.mjs +873 -0
  41. package/dist/generated/capability-surface.mjs +66 -0
  42. package/dist/generated/node-wire-contract.json +122 -0
  43. package/dist/index.d.ts +239 -0
  44. package/dist/index.mjs +22 -0
  45. package/dist/native-loader.mjs +112 -0
  46. package/dist/transport-contract.mjs +87 -0
  47. package/package.json +50 -0
@@ -0,0 +1,66 @@
1
+ // @generated by `cargo run -p xtask -- gen-capability-surface`.
2
+ // Source: capabilities/feature-surface-v1.json. Do not edit directly.
3
+
4
+ export const CAPABILITY_DESCRIPTOR_SCHEMA_VERSION = 1;
5
+ export const CAPABILITY_DESCRIPTOR_DIGEST = "sha256:02e572e1010d2a3d440b69eef260cdf3b2d7f5a88f8c28ebe9fa486e184e722e";
6
+
7
+ export const NODE_BINDING_OPERATIONS = [
8
+ {
9
+ "id": "analysis-facts-json",
10
+ "compiled_prerequisites": []
11
+ },
12
+ {
13
+ "id": "analysis-json",
14
+ "compiled_prerequisites": []
15
+ },
16
+ {
17
+ "id": "ascii",
18
+ "compiled_prerequisites": []
19
+ },
20
+ {
21
+ "id": "document-analysis-facts-json",
22
+ "compiled_prerequisites": []
23
+ },
24
+ {
25
+ "id": "document-analysis-json",
26
+ "compiled_prerequisites": []
27
+ },
28
+ {
29
+ "id": "jpeg",
30
+ "compiled_prerequisites": [
31
+ "svg"
32
+ ]
33
+ },
34
+ {
35
+ "id": "layout-json",
36
+ "compiled_prerequisites": []
37
+ },
38
+ {
39
+ "id": "pdf",
40
+ "compiled_prerequisites": [
41
+ "svg"
42
+ ]
43
+ },
44
+ {
45
+ "id": "png",
46
+ "compiled_prerequisites": [
47
+ "svg"
48
+ ]
49
+ },
50
+ {
51
+ "id": "semantic-json",
52
+ "compiled_prerequisites": []
53
+ },
54
+ {
55
+ "id": "svg",
56
+ "compiled_prerequisites": []
57
+ },
58
+ {
59
+ "id": "svg-plan-json",
60
+ "compiled_prerequisites": []
61
+ },
62
+ {
63
+ "id": "validation-json",
64
+ "compiled_prerequisites": []
65
+ }
66
+ ];
@@ -0,0 +1,122 @@
1
+ {
2
+ "schema_version": 1,
3
+ "package_id": "@mermanjs/node",
4
+ "artifact_id": "merman-node-static-svg",
5
+ "transport_api_version": 1,
6
+ "binding_result_payload_version": 1,
7
+ "artifact": {
8
+ "capability_ids": [
9
+ "layout-cytoscape",
10
+ "layout-elk",
11
+ "svg"
12
+ ],
13
+ "output_ids": [
14
+ "svg"
15
+ ],
16
+ "output_contracts": [
17
+ {
18
+ "id": "svg",
19
+ "media_type": "image/svg+xml",
20
+ "system_fonts": null,
21
+ "embedded_images": null
22
+ }
23
+ ],
24
+ "system_adapter_ids": [],
25
+ "operation_ids": [
26
+ "layout-json",
27
+ "semantic-json",
28
+ "svg",
29
+ "svg-plan-json"
30
+ ],
31
+ "metadata_ids": [
32
+ "diagram-family-capabilities",
33
+ "presentation-catalog",
34
+ "supported-diagrams",
35
+ "supported-themes"
36
+ ],
37
+ "option_group_ids": [
38
+ "environment",
39
+ "fixed_local_offset_minutes",
40
+ "fixed_today",
41
+ "layout",
42
+ "parse",
43
+ "presentation",
44
+ "resources",
45
+ "runtime_policy",
46
+ "site_config",
47
+ "svg",
48
+ "version"
49
+ ],
50
+ "constructor_service_ids": [],
51
+ "text_measurement_provider_ids": [
52
+ "vendored"
53
+ ]
54
+ },
55
+ "documents": {
56
+ "identity": {
57
+ "max_utf8_bytes": 4096,
58
+ "max_depth": 8,
59
+ "max_members": 128,
60
+ "max_tokens": 256,
61
+ "max_string_utf8_bytes": 1024
62
+ },
63
+ "binding_options": {
64
+ "max_utf8_bytes": 1048576,
65
+ "max_depth": 64,
66
+ "max_members": 65536,
67
+ "max_tokens": 262144,
68
+ "max_string_utf8_bytes": 1048576
69
+ },
70
+ "request": {
71
+ "max_utf8_bytes": 10485760,
72
+ "max_depth": 8,
73
+ "max_members": 16,
74
+ "max_tokens": 64,
75
+ "max_string_utf8_bytes": 8388608
76
+ },
77
+ "runtime_catalog": {
78
+ "max_utf8_bytes": 1048576,
79
+ "max_depth": 64,
80
+ "max_members": 65536,
81
+ "max_tokens": 262144,
82
+ "max_string_utf8_bytes": 1048576
83
+ },
84
+ "response": {
85
+ "max_utf8_bytes": 27262976,
86
+ "max_depth": 8,
87
+ "max_members": 32,
88
+ "max_tokens": 128,
89
+ "max_string_utf8_bytes": 16777216
90
+ },
91
+ "error": {
92
+ "max_utf8_bytes": 262144,
93
+ "max_depth": 8,
94
+ "max_members": 32,
95
+ "max_tokens": 128,
96
+ "max_string_utf8_bytes": 65536
97
+ },
98
+ "metadata": {
99
+ "max_utf8_bytes": 8388608,
100
+ "max_depth": 64,
101
+ "max_members": 131072,
102
+ "max_tokens": 524288,
103
+ "max_string_utf8_bytes": 8388608
104
+ }
105
+ },
106
+ "fields": {
107
+ "operation_id_utf8_bytes": 128,
108
+ "media_type_utf8_bytes": 128,
109
+ "metadata_id_utf8_bytes": 128,
110
+ "uri_utf8_bytes": 16384,
111
+ "source_utf8_bytes": 8388608,
112
+ "options_json_utf8_bytes": 1048576,
113
+ "data_utf8_bytes": 16777216,
114
+ "metadata_json_utf8_bytes": 8388608,
115
+ "error_code_name_utf8_bytes": 128,
116
+ "error_kind_utf8_bytes": 128,
117
+ "error_message_utf8_bytes": 65536,
118
+ "capability_id_utf8_bytes": 128,
119
+ "package_version_utf8_bytes": 128,
120
+ "contract_digest_utf8_bytes": 128
121
+ }
122
+ }
@@ -0,0 +1,239 @@
1
+ export type MermanResourceProfile =
2
+ | "interactive"
3
+ | "constrained"
4
+ | "trusted-native"
5
+ | "unbounded-for-trusted-input";
6
+
7
+ export interface MermanBindingOptions {
8
+ version?: 2;
9
+ runtime_policy?: "deterministic";
10
+ resources?: {
11
+ profile?: MermanResourceProfile;
12
+ limits?: Record<string, number>;
13
+ };
14
+ [key: string]: unknown;
15
+ }
16
+
17
+ export interface CreateNodeEngineOptions {
18
+ bindingOptions?: MermanBindingOptions;
19
+ concurrency?: number;
20
+ maxQueue?: number;
21
+ }
22
+
23
+ export interface RenderSvgOptions {
24
+ /**
25
+ * Cancels only while the request is waiting in the JS queue. Work that has started is not
26
+ * preempted and its Promise settles with the actual operation result.
27
+ */
28
+ signal?: AbortSignal;
29
+ /** Raw per-request options JSON merged by the shared binding contract. */
30
+ optionsJson?: string;
31
+ }
32
+
33
+ export interface MermanOperationRequest {
34
+ operationId: string;
35
+ source: string;
36
+ uri?: string | null;
37
+ /** Raw per-request options JSON merged over the reusable engine baseline. */
38
+ optionsJson?: string;
39
+ }
40
+
41
+ export interface MermanOperationResult {
42
+ operation_id: string;
43
+ media_type: string;
44
+ data: string;
45
+ metadata_json: string;
46
+ }
47
+
48
+ export interface MermanTextMeasurementCatalog {
49
+ protocol_version: number;
50
+ provider_ids: string[];
51
+ [key: string]: unknown;
52
+ }
53
+
54
+ export interface MermanRuntimeResourceLimit {
55
+ id: string;
56
+ phase: string;
57
+ description: string;
58
+ overridable: boolean;
59
+ hard_cap: boolean;
60
+ minimum_value: number;
61
+ operation_ids: string[];
62
+ [key: string]: unknown;
63
+ }
64
+
65
+ export interface MermanRuntimeResourceProfile {
66
+ id: string;
67
+ purpose: string;
68
+ trust_assumption: string;
69
+ recommended_binding_default: boolean;
70
+ limits: Record<string, number | null>;
71
+ [key: string]: unknown;
72
+ }
73
+
74
+ export interface MermanRuntimeSystemFontContract {
75
+ source_id: string;
76
+ discovery: string;
77
+ cache_scope: string;
78
+ host_dependent: boolean;
79
+ caller_configurable: boolean;
80
+ resource_bounded: boolean;
81
+ [key: string]: unknown;
82
+ }
83
+
84
+ export interface MermanRuntimeEmbeddedImageLimits {
85
+ max_bytes_per_image: number | null;
86
+ max_total_bytes: number | null;
87
+ max_pixels_per_image: number | null;
88
+ max_total_pixels: number | null;
89
+ [key: string]: unknown;
90
+ }
91
+
92
+ export interface MermanRuntimeEmbeddedImageContract {
93
+ source_ids: string[];
94
+ filesystem_access: boolean;
95
+ network_access: boolean;
96
+ caller_configurable: boolean;
97
+ limits: MermanRuntimeEmbeddedImageLimits;
98
+ [key: string]: unknown;
99
+ }
100
+
101
+ export interface MermanRuntimeOutputContract {
102
+ id: string;
103
+ media_type: string;
104
+ system_fonts: MermanRuntimeSystemFontContract | null;
105
+ embedded_images: MermanRuntimeEmbeddedImageContract | null;
106
+ [key: string]: unknown;
107
+ }
108
+
109
+ export interface MermanRuntimePayloadSchema {
110
+ id: string;
111
+ version: number;
112
+ [key: string]: unknown;
113
+ }
114
+
115
+ export interface MermanRuntimeConstructorResourceLimit {
116
+ id: string;
117
+ phase: string;
118
+ unit: string;
119
+ description: string;
120
+ value: number;
121
+ [key: string]: unknown;
122
+ }
123
+
124
+ export interface MermanRuntimeConstructorServiceContract {
125
+ id: string;
126
+ provided_text_measurement_provider_ids: string[];
127
+ resource_limits: MermanRuntimeConstructorResourceLimit[];
128
+ [key: string]: unknown;
129
+ }
130
+
131
+ export interface MermanRuntimeCatalog {
132
+ schema_version: 1;
133
+ transport_api_version: 1;
134
+ package_version: string;
135
+ options_schema_versions: number[];
136
+ payload_schemas: MermanRuntimePayloadSchema[];
137
+ metadata_ids: string[];
138
+ option_group_ids: string[];
139
+ constructor_service_ids: string[];
140
+ constructor_service_contracts: MermanRuntimeConstructorServiceContract[];
141
+ capabilities: {
142
+ capability_ids: string[];
143
+ output_ids: string[];
144
+ operation_ids: string[];
145
+ system_adapter_ids: string[];
146
+ text_measurement: MermanTextMeasurementCatalog | null;
147
+ [key: string]: unknown;
148
+ };
149
+ output_contracts: MermanRuntimeOutputContract[];
150
+ registry: {
151
+ diagram_family_count: number;
152
+ [key: string]: unknown;
153
+ };
154
+ resources: {
155
+ general_binding_default_profile: string;
156
+ cli_default_profile: string;
157
+ limits: MermanRuntimeResourceLimit[];
158
+ profiles: MermanRuntimeResourceProfile[];
159
+ [key: string]: unknown;
160
+ };
161
+ [key: string]: unknown;
162
+ }
163
+
164
+ export interface MermanQueueState {
165
+ readonly active: number;
166
+ readonly pending: number;
167
+ readonly concurrency: number;
168
+ readonly maxQueue: number;
169
+ readonly state: "open" | "disposing" | "disposed";
170
+ }
171
+
172
+ export declare class MermanEngine {
173
+ private constructor();
174
+ readonly queueState: MermanQueueState;
175
+ readonly runtimeCatalog: MermanRuntimeCatalog;
176
+ renderSvg(source: string, options?: RenderSvgOptions): Promise<string>;
177
+ /** Synchronous rendering is intended only for explicit SSG build paths. */
178
+ renderSvgSync(source: string, options?: Omit<RenderSvgOptions, "signal">): string;
179
+ svgPlanJson(source: string, options?: RenderSvgOptions): Promise<string>;
180
+ svgPlanJsonSync(
181
+ source: string,
182
+ options?: Omit<RenderSvgOptions, "signal">,
183
+ ): string;
184
+ metadataJson(id: string): string;
185
+ executeOperation(
186
+ request: MermanOperationRequest,
187
+ options?: Pick<RenderSvgOptions, "signal">,
188
+ ): Promise<MermanOperationResult>;
189
+ executeOperationSync(request: MermanOperationRequest): MermanOperationResult;
190
+ dispose(): Promise<void>;
191
+ }
192
+
193
+ export declare function createNodeEngine(
194
+ options?: CreateNodeEngineOptions,
195
+ ): Promise<MermanEngine>;
196
+
197
+ export declare class MermanError extends Error {
198
+ readonly code: string;
199
+ }
200
+
201
+ /**
202
+ * A lossless unsigned resource count. Safe integers use `number`; wider `u64` values use a
203
+ * canonical decimal `string`.
204
+ */
205
+ export type MermanResourceCount = number | string;
206
+
207
+ export interface MermanResourceErrorDetails {
208
+ readonly cause: string;
209
+ readonly limit_id: string;
210
+ readonly phase: string;
211
+ readonly actual: MermanResourceCount;
212
+ readonly max: MermanResourceCount;
213
+ readonly profile: string;
214
+ }
215
+
216
+ export declare class MermanOperationError extends MermanError {
217
+ readonly status: number | null;
218
+ readonly codeName: string | null;
219
+ readonly kind: "generic" | "unknown-operation" | "missing-capability" | string;
220
+ readonly capabilityId: string | null;
221
+ readonly resourceDetails: MermanResourceErrorDetails | null;
222
+ }
223
+
224
+ export declare class MermanQueueSaturatedError extends MermanError {
225
+ readonly maxQueue: number;
226
+ }
227
+
228
+ export declare class MermanDisposedError extends MermanError {}
229
+ export declare class MermanInvalidTransportError extends MermanError {}
230
+ export declare class MermanLifecycleError extends MermanError {}
231
+ export declare class MermanMissingPlatformPackageError extends MermanError {
232
+ readonly packageName: string;
233
+ readonly target: string;
234
+ }
235
+ export declare class MermanUnsupportedTargetError extends MermanError {
236
+ readonly platform: string;
237
+ readonly arch: string;
238
+ readonly libc: string | null;
239
+ }
package/dist/index.mjs ADDED
@@ -0,0 +1,22 @@
1
+ import { loadNativeTransport } from "./candidates/native.mjs";
2
+ import {
3
+ MermanEngine,
4
+ createNodeEngine as createEngineWithTransport,
5
+ } from "./engine.mjs";
6
+
7
+ export { MermanEngine };
8
+
9
+ export function createNodeEngine(options) {
10
+ return createEngineWithTransport(options, { loadTransport: loadNativeTransport });
11
+ }
12
+
13
+ export {
14
+ MermanDisposedError,
15
+ MermanError,
16
+ MermanInvalidTransportError,
17
+ MermanLifecycleError,
18
+ MermanMissingPlatformPackageError,
19
+ MermanOperationError,
20
+ MermanQueueSaturatedError,
21
+ MermanUnsupportedTargetError,
22
+ } from "./errors.mjs";
@@ -0,0 +1,112 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ import {
4
+ MermanInvalidTransportError,
5
+ MermanMissingPlatformPackageError,
6
+ MermanUnsupportedTargetError,
7
+ parseRuntimeCatalogJsonText,
8
+ } from "./errors.mjs";
9
+
10
+ const TARGET_PACKAGES = Object.freeze({
11
+ "darwin-arm64": "@mermanjs/node-darwin-arm64",
12
+ "darwin-x64": "@mermanjs/node-darwin-x64",
13
+ "linux-x64-gnu": "@mermanjs/node-linux-x64-gnu",
14
+ "linux-x64-musl": "@mermanjs/node-linux-x64-musl",
15
+ "win32-x64-msvc": "@mermanjs/node-win32-x64-msvc",
16
+ });
17
+
18
+ const requireFromPackage = createRequire(import.meta.url);
19
+ const loaderPackageManifest = requireFromPackage("../package.json");
20
+ const loaderPackageVersion = loaderPackageManifest?.version;
21
+
22
+ if (typeof loaderPackageVersion !== "string" || loaderPackageVersion.length === 0) {
23
+ throw new Error("The Merman Node package manifest must declare a non-empty version.");
24
+ }
25
+
26
+ export function nodeLoaderPackageVersion() {
27
+ return loaderPackageVersion;
28
+ }
29
+
30
+ export function assertRuntimePackageVersion(value) {
31
+ const catalog = parseRuntimeCatalogJsonText(value);
32
+ if (catalog?.package_version !== loaderPackageVersion) {
33
+ throw new MermanInvalidTransportError(
34
+ `The Merman runtime package version ${JSON.stringify(catalog?.package_version)} does not match the loader package version ${JSON.stringify(loaderPackageVersion)}.`,
35
+ );
36
+ }
37
+ return value;
38
+ }
39
+
40
+ export function nativePackageName(target) {
41
+ const packageName = TARGET_PACKAGES[target];
42
+ if (!packageName) {
43
+ throw new MermanUnsupportedTargetError({
44
+ platform: target,
45
+ arch: "unknown",
46
+ reason: `Unknown Merman Node target id: ${target}.`,
47
+ });
48
+ }
49
+ return packageName;
50
+ }
51
+
52
+ export function resolveNodeTarget({
53
+ platform = process.platform,
54
+ arch = process.arch,
55
+ report = platform === "linux" ? currentProcessReport() : null,
56
+ } = {}) {
57
+ if (platform === "darwin" && (arch === "arm64" || arch === "x64")) {
58
+ return `darwin-${arch}`;
59
+ }
60
+ if (platform === "win32" && arch === "x64") return "win32-x64-msvc";
61
+ if (platform === "linux" && arch === "x64") {
62
+ const libc = linuxLibc(report);
63
+ return `linux-x64-${libc}`;
64
+ }
65
+ throw new MermanUnsupportedTargetError({ platform, arch });
66
+ }
67
+
68
+ export function loadNativeBinding({
69
+ platform = process.platform,
70
+ arch = process.arch,
71
+ report = platform === "linux" ? currentProcessReport() : null,
72
+ loadPackage = requireFromPackage,
73
+ } = {}) {
74
+ const target = resolveNodeTarget({ platform, arch, report });
75
+ const packageName = nativePackageName(target);
76
+ try {
77
+ return loadPackage(packageName);
78
+ } catch (cause) {
79
+ if (isMissingModule(cause)) {
80
+ throw new MermanMissingPlatformPackageError({ packageName, target, cause });
81
+ }
82
+ throw cause;
83
+ }
84
+ }
85
+
86
+ function linuxLibc(report) {
87
+ if (report?.header?.glibcVersionRuntime) return "gnu";
88
+ if (
89
+ Array.isArray(report?.sharedObjects) &&
90
+ report.sharedObjects.some((item) => /(?:^|[/\\])ld-musl-[^/\\]+\.so(?:\.1)?$/.test(item))
91
+ ) {
92
+ return "musl";
93
+ }
94
+ throw new MermanUnsupportedTargetError({
95
+ platform: "linux",
96
+ arch: "x64",
97
+ reason:
98
+ "Cannot determine Linux libc from process.report; refusing to guess a platform package.",
99
+ });
100
+ }
101
+
102
+ function currentProcessReport() {
103
+ return typeof process.report?.getReport === "function" ? process.report.getReport() : null;
104
+ }
105
+
106
+ function isMissingModule(error) {
107
+ return Boolean(
108
+ error &&
109
+ typeof error === "object" &&
110
+ (error.code === "MODULE_NOT_FOUND" || error.code === "ERR_MODULE_NOT_FOUND"),
111
+ );
112
+ }
@@ -0,0 +1,87 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ const requireFromModule = createRequire(import.meta.url);
4
+ const contract = requireFromModule("./generated/node-wire-contract.json");
5
+
6
+ validateContract(contract);
7
+
8
+ export const NODE_WIRE_CONTRACT = deepFreeze(contract);
9
+ export const NODE_TRANSPORT_LIMITS = NODE_WIRE_CONTRACT.documents;
10
+ export const NODE_TRANSPORT_FIELD_LIMITS = NODE_WIRE_CONTRACT.fields;
11
+
12
+ function validateContract(value) {
13
+ if (
14
+ !value ||
15
+ value.schema_version !== 1 ||
16
+ value.package_id !== "@mermanjs/node" ||
17
+ value.artifact_id !== "merman-node-static-svg" ||
18
+ value.transport_api_version !== 1 ||
19
+ value.binding_result_payload_version !== 1 ||
20
+ !value.artifact ||
21
+ !value.documents ||
22
+ !value.fields
23
+ ) {
24
+ throw new Error("The generated Node wire contract is invalid.");
25
+ }
26
+ for (const field of [
27
+ "capability_ids",
28
+ "output_ids",
29
+ "system_adapter_ids",
30
+ "operation_ids",
31
+ "metadata_ids",
32
+ "option_group_ids",
33
+ "constructor_service_ids",
34
+ "text_measurement_provider_ids",
35
+ ]) {
36
+ const ids = value.artifact[field];
37
+ if (
38
+ !Array.isArray(ids) ||
39
+ ids.some((id) => typeof id !== "string" || id.length === 0) ||
40
+ ids.some((id, index) => index > 0 && ids[index - 1] >= id)
41
+ ) {
42
+ throw new Error(`The generated Node artifact field \`${field}\` is invalid.`);
43
+ }
44
+ }
45
+ if (
46
+ !Array.isArray(value.artifact.output_contracts) ||
47
+ value.artifact.output_contracts.length !== value.artifact.output_ids.length ||
48
+ value.artifact.output_contracts.some((contract, index) =>
49
+ !contract ||
50
+ contract.id !== value.artifact.output_ids[index] ||
51
+ typeof contract.media_type !== "string" ||
52
+ contract.media_type.length === 0 ||
53
+ !(contract.system_fonts === null || isObject(contract.system_fonts)) ||
54
+ !(contract.embedded_images === null || isObject(contract.embedded_images))
55
+ )
56
+ ) {
57
+ throw new Error("The generated Node artifact output contracts are invalid.");
58
+ }
59
+ for (const [id, limits] of Object.entries(value.documents)) {
60
+ if (
61
+ !limits ||
62
+ !Number.isSafeInteger(limits.max_utf8_bytes) ||
63
+ !Number.isSafeInteger(limits.max_depth) ||
64
+ !Number.isSafeInteger(limits.max_members) ||
65
+ !Number.isSafeInteger(limits.max_tokens) ||
66
+ !Number.isSafeInteger(limits.max_string_utf8_bytes) ||
67
+ Object.values(limits).some((limit) => limit <= 0)
68
+ ) {
69
+ throw new Error(`The generated Node wire document limit \`${id}\` is invalid.`);
70
+ }
71
+ }
72
+ for (const [id, limit] of Object.entries(value.fields)) {
73
+ if (!Number.isSafeInteger(limit) || limit <= 0) {
74
+ throw new Error(`The generated Node wire field limit \`${id}\` is invalid.`);
75
+ }
76
+ }
77
+ }
78
+
79
+ function isObject(value) {
80
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
81
+ }
82
+
83
+ function deepFreeze(value) {
84
+ if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
85
+ for (const child of Object.values(value)) deepFreeze(child);
86
+ return Object.freeze(value);
87
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@mermanjs/node",
3
+ "version": "0.8.0-alpha.5",
4
+ "description": "Experimental native Node.js and static-site rendering bindings for Merman.",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=22.0.0"
8
+ },
9
+ "main": "./dist/index.mjs",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.mjs"
15
+ }
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/Latias94/merman.git"
20
+ },
21
+ "homepage": "https://github.com/Latias94/merman/tree/main/platforms/node#readme",
22
+ "keywords": [
23
+ "mermaid",
24
+ "diagram",
25
+ "svg",
26
+ "node",
27
+ "ssg",
28
+ "napi"
29
+ ],
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "files": [
34
+ "CHANGELOG.md",
35
+ "dist",
36
+ "LICENSE-APACHE",
37
+ "LICENSE-MIT",
38
+ "README.md",
39
+ "THIRD_PARTY_LICENSES",
40
+ "THIRD_PARTY_NOTICES.md"
41
+ ],
42
+ "license": "MIT OR Apache-2.0",
43
+ "optionalDependencies": {
44
+ "@mermanjs/node-darwin-arm64": "0.8.0-alpha.5",
45
+ "@mermanjs/node-darwin-x64": "0.8.0-alpha.5",
46
+ "@mermanjs/node-linux-x64-gnu": "0.8.0-alpha.5",
47
+ "@mermanjs/node-linux-x64-musl": "0.8.0-alpha.5",
48
+ "@mermanjs/node-win32-x64-msvc": "0.8.0-alpha.5"
49
+ }
50
+ }