space-data-module-sdk 0.3.0 → 0.4.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/package.json +1 -1
- package/src/bundle/constants.js +5 -0
- package/src/compiler/compileModule.js +267 -4
- package/src/deployment/index.js +6 -0
- package/src/index.d.ts +15 -1
package/package.json
CHANGED
package/src/bundle/constants.js
CHANGED
|
@@ -9,3 +9,8 @@ export const SDS_DEPLOYMENT_SECTION_NAME = "sds.deployment";
|
|
|
9
9
|
export const SDS_DEPLOYMENT_ENTRY_ID = "deployment-plan";
|
|
10
10
|
export const SDS_DEPLOYMENT_MEDIA_TYPE =
|
|
11
11
|
"application/vnd.space-data.module.deployment+json";
|
|
12
|
+
export const SDS_GUEST_LINK_OBJECT_ENTRY_ID = "guest-link-object";
|
|
13
|
+
export const SDS_GUEST_LINK_METADATA_ENTRY_ID = "guest-link-metadata";
|
|
14
|
+
export const SDS_GUEST_LINK_SECTION_NAME = "sds.guest-link";
|
|
15
|
+
export const SDS_GUEST_LINK_MEDIA_TYPE =
|
|
16
|
+
"application/vnd.space-data.module.guest-link+json";
|
|
@@ -30,6 +30,16 @@ import {
|
|
|
30
30
|
generateX25519Keypair,
|
|
31
31
|
} from "../transport/index.js";
|
|
32
32
|
import { createSingleFileBundle } from "../bundle/index.js";
|
|
33
|
+
import {
|
|
34
|
+
SDS_GUEST_LINK_MEDIA_TYPE,
|
|
35
|
+
SDS_GUEST_LINK_METADATA_ENTRY_ID,
|
|
36
|
+
SDS_GUEST_LINK_OBJECT_ENTRY_ID,
|
|
37
|
+
SDS_GUEST_LINK_SECTION_NAME,
|
|
38
|
+
} from "../bundle/constants.js";
|
|
39
|
+
import {
|
|
40
|
+
decodeUnsignedLeb128,
|
|
41
|
+
parseWasmModuleSections,
|
|
42
|
+
} from "../bundle/wasm.js";
|
|
33
43
|
import {
|
|
34
44
|
base64ToBytes,
|
|
35
45
|
bytesToBase64,
|
|
@@ -76,6 +86,201 @@ function buildCompilerArgs(exportedSymbols, options = {}) {
|
|
|
76
86
|
return args;
|
|
77
87
|
}
|
|
78
88
|
|
|
89
|
+
function guestLinkSymbolPrefix(pluginId) {
|
|
90
|
+
const normalized = String(pluginId ?? "module");
|
|
91
|
+
const ascii = Array.from(new TextEncoder().encode(normalized))
|
|
92
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
93
|
+
.join("")
|
|
94
|
+
.slice(0, 24);
|
|
95
|
+
return `sdm_guest_${ascii}_`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function parseStrongDefinedIdentifiers(nmOutput = "") {
|
|
99
|
+
const identifiers = new Set();
|
|
100
|
+
for (const line of String(nmOutput).split(/\r?\n/)) {
|
|
101
|
+
const match = line.match(/^\S+\s+([A-Za-z])\s+(.+)$/);
|
|
102
|
+
if (!match) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const symbolType = match[1];
|
|
106
|
+
if (!"TDBCGRSV".includes(symbolType)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const demangled = match[2].trim();
|
|
110
|
+
const baseName = demangled
|
|
111
|
+
.replace(/\(.*$/, "")
|
|
112
|
+
.split("::")
|
|
113
|
+
.at(-1)
|
|
114
|
+
?.trim();
|
|
115
|
+
if (!C_IDENTIFIER.test(baseName ?? "")) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
identifiers.add(baseName);
|
|
119
|
+
}
|
|
120
|
+
return Array.from(identifiers).sort();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const WASM_SYM_BINDING_WEAK = 0x01;
|
|
124
|
+
const WASM_SYM_BINDING_LOCAL = 0x02;
|
|
125
|
+
const WASM_SYM_UNDEFINED = 0x10;
|
|
126
|
+
const WASM_SYM_EXPLICIT_NAME = 0x40;
|
|
127
|
+
const WASM_SYMBOL_KIND_FUNCTION = 0;
|
|
128
|
+
const WASM_SYMBOL_KIND_DATA = 1;
|
|
129
|
+
const WASM_SYMBOL_KIND_GLOBAL = 2;
|
|
130
|
+
const WASM_SYMBOL_KIND_SECTION = 3;
|
|
131
|
+
const WASM_SYMBOL_KIND_EVENT = 4;
|
|
132
|
+
const WASM_SYMBOL_KIND_TABLE = 5;
|
|
133
|
+
const LINKING_SYMBOL_TABLE_SUBSECTION_ID = 8;
|
|
134
|
+
const textDecoder = new TextDecoder();
|
|
135
|
+
|
|
136
|
+
function decodeWasmName(bytes, offset) {
|
|
137
|
+
const lengthInfo = decodeUnsignedLeb128(bytes, offset);
|
|
138
|
+
const nameStart = lengthInfo.nextOffset;
|
|
139
|
+
const nameEnd = nameStart + lengthInfo.value;
|
|
140
|
+
if (nameEnd > bytes.length) {
|
|
141
|
+
throw new Error("WASM name extends past end of symbol payload.");
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
value: textDecoder.decode(bytes.subarray(nameStart, nameEnd)),
|
|
145
|
+
nextOffset: nameEnd,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function parseDefinedLinkSymbolsFromObjectBytes(objectBytes) {
|
|
150
|
+
const parsed = parseWasmModuleSections(objectBytes);
|
|
151
|
+
const linkingSection = parsed.sections.find(
|
|
152
|
+
(section) => section.id === 0 && section.name === "linking",
|
|
153
|
+
);
|
|
154
|
+
if (!linkingSection) {
|
|
155
|
+
throw new Error("Guest-link object is missing a linking custom section.");
|
|
156
|
+
}
|
|
157
|
+
const payload = linkingSection.dataBytes;
|
|
158
|
+
let offset = decodeUnsignedLeb128(payload, 0).nextOffset;
|
|
159
|
+
const identifiers = new Set();
|
|
160
|
+
while (offset < payload.length) {
|
|
161
|
+
const subsectionId = payload[offset++];
|
|
162
|
+
const sizeInfo = decodeUnsignedLeb128(payload, offset);
|
|
163
|
+
offset = sizeInfo.nextOffset;
|
|
164
|
+
const subsectionEnd = offset + sizeInfo.value;
|
|
165
|
+
if (subsectionEnd > payload.length) {
|
|
166
|
+
throw new Error("Linking subsection extends past end of payload.");
|
|
167
|
+
}
|
|
168
|
+
if (subsectionId !== LINKING_SYMBOL_TABLE_SUBSECTION_ID) {
|
|
169
|
+
offset = subsectionEnd;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
let cursor = offset;
|
|
173
|
+
const countInfo = decodeUnsignedLeb128(payload, cursor);
|
|
174
|
+
cursor = countInfo.nextOffset;
|
|
175
|
+
for (let symbolIndex = 0; symbolIndex < countInfo.value; symbolIndex += 1) {
|
|
176
|
+
const kind = payload[cursor++];
|
|
177
|
+
const flagsInfo = decodeUnsignedLeb128(payload, cursor);
|
|
178
|
+
const flags = flagsInfo.value;
|
|
179
|
+
cursor = flagsInfo.nextOffset;
|
|
180
|
+
let name = "";
|
|
181
|
+
if (
|
|
182
|
+
kind === WASM_SYMBOL_KIND_FUNCTION ||
|
|
183
|
+
kind === WASM_SYMBOL_KIND_GLOBAL ||
|
|
184
|
+
kind === WASM_SYMBOL_KIND_EVENT ||
|
|
185
|
+
kind === WASM_SYMBOL_KIND_TABLE
|
|
186
|
+
) {
|
|
187
|
+
cursor = decodeUnsignedLeb128(payload, cursor).nextOffset;
|
|
188
|
+
if (
|
|
189
|
+
(flags & WASM_SYM_UNDEFINED) === 0 ||
|
|
190
|
+
(flags & WASM_SYM_EXPLICIT_NAME) !== 0
|
|
191
|
+
) {
|
|
192
|
+
const nameInfo = decodeWasmName(payload, cursor);
|
|
193
|
+
name = nameInfo.value;
|
|
194
|
+
cursor = nameInfo.nextOffset;
|
|
195
|
+
}
|
|
196
|
+
} else if (kind === WASM_SYMBOL_KIND_DATA) {
|
|
197
|
+
const nameInfo = decodeWasmName(payload, cursor);
|
|
198
|
+
name = nameInfo.value;
|
|
199
|
+
cursor = nameInfo.nextOffset;
|
|
200
|
+
if ((flags & WASM_SYM_UNDEFINED) === 0) {
|
|
201
|
+
cursor = decodeUnsignedLeb128(payload, cursor).nextOffset;
|
|
202
|
+
cursor = decodeUnsignedLeb128(payload, cursor).nextOffset;
|
|
203
|
+
cursor = decodeUnsignedLeb128(payload, cursor).nextOffset;
|
|
204
|
+
}
|
|
205
|
+
} else if (kind === WASM_SYMBOL_KIND_SECTION) {
|
|
206
|
+
cursor = decodeUnsignedLeb128(payload, cursor).nextOffset;
|
|
207
|
+
} else {
|
|
208
|
+
throw new Error(`Unsupported WASM linking symbol kind: ${kind}`);
|
|
209
|
+
}
|
|
210
|
+
if ((flags & WASM_SYM_UNDEFINED) !== 0) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if ((flags & WASM_SYM_BINDING_LOCAL) !== 0) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if ((flags & WASM_SYM_BINDING_WEAK) !== 0) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (!C_IDENTIFIER.test(name)) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
identifiers.add(name);
|
|
223
|
+
}
|
|
224
|
+
return Array.from(identifiers).sort();
|
|
225
|
+
}
|
|
226
|
+
throw new Error("Guest-link object is missing a symbol table subsection.");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function deriveGuestLinkRenameArgs({
|
|
230
|
+
objectBytes,
|
|
231
|
+
pluginId,
|
|
232
|
+
methodIds = [],
|
|
233
|
+
} = {}) {
|
|
234
|
+
const identifiers = parseDefinedLinkSymbolsFromObjectBytes(objectBytes);
|
|
235
|
+
const prefix = guestLinkSymbolPrefix(pluginId);
|
|
236
|
+
const renamedIdentifiers = Array.from(
|
|
237
|
+
new Set([...identifiers, ...methodIds.filter((value) => C_IDENTIFIER.test(value))]),
|
|
238
|
+
).sort();
|
|
239
|
+
return {
|
|
240
|
+
prefix,
|
|
241
|
+
identifiers: renamedIdentifiers,
|
|
242
|
+
renameArgs: renamedIdentifiers.map(
|
|
243
|
+
(identifier) => `-D${identifier}=${prefix}${identifier}`,
|
|
244
|
+
),
|
|
245
|
+
methodSymbols: Object.fromEntries(
|
|
246
|
+
methodIds.map((methodId) => [methodId, `${prefix}${methodId}`]),
|
|
247
|
+
),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function createGuestLinkBundleEntries(guestLink) {
|
|
252
|
+
if (!guestLink?.objectBytes || guestLink.objectBytes.length === 0) {
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
return [
|
|
256
|
+
{
|
|
257
|
+
entryId: SDS_GUEST_LINK_OBJECT_ENTRY_ID,
|
|
258
|
+
role: "auxiliary",
|
|
259
|
+
sectionName: SDS_GUEST_LINK_SECTION_NAME,
|
|
260
|
+
payloadEncoding: "raw-bytes",
|
|
261
|
+
mediaType: "application/wasm",
|
|
262
|
+
payload: guestLink.objectBytes,
|
|
263
|
+
description: "Prefixed guest-link wasm object for monolithic flow linking.",
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
entryId: SDS_GUEST_LINK_METADATA_ENTRY_ID,
|
|
267
|
+
role: "auxiliary",
|
|
268
|
+
sectionName: SDS_GUEST_LINK_SECTION_NAME,
|
|
269
|
+
payloadEncoding: "json-utf8",
|
|
270
|
+
mediaType: SDS_GUEST_LINK_MEDIA_TYPE,
|
|
271
|
+
payload: {
|
|
272
|
+
version: 1,
|
|
273
|
+
format: "wasm-object",
|
|
274
|
+
symbolPrefix: guestLink.symbolPrefix,
|
|
275
|
+
methodSymbols: guestLink.methodSymbols,
|
|
276
|
+
methodIds: Object.keys(guestLink.methodSymbols ?? {}),
|
|
277
|
+
language: guestLink.language,
|
|
278
|
+
},
|
|
279
|
+
description: "Guest-link metadata for monolithic flow linking.",
|
|
280
|
+
},
|
|
281
|
+
];
|
|
282
|
+
}
|
|
283
|
+
|
|
79
284
|
async function getInvokeCppSupportFiles() {
|
|
80
285
|
const [runtimeHeaders, schemaHeaders] = await Promise.all([
|
|
81
286
|
getFlatbuffersCppRuntimeHeaders(),
|
|
@@ -114,6 +319,8 @@ function removeEmceptionDirectory(emception, directoryPath) {
|
|
|
114
319
|
|
|
115
320
|
async function compileWithEmception(options = {}) {
|
|
116
321
|
const {
|
|
322
|
+
manifest,
|
|
323
|
+
language,
|
|
117
324
|
sourceCompilerCommand,
|
|
118
325
|
sourceExtension,
|
|
119
326
|
sourceCode,
|
|
@@ -140,6 +347,7 @@ async function compileWithEmception(options = {}) {
|
|
|
140
347
|
const invokeHeaderPath = path.posix.join(workDir, "space_data_module_invoke.h");
|
|
141
348
|
const invokeSourcePath = path.posix.join(workDir, "plugin-invoke-bridge.cpp");
|
|
142
349
|
const sourceObjectPath = path.posix.join(workDir, "module.o");
|
|
350
|
+
const linkObjectPath = path.posix.join(workDir, "module-link.o");
|
|
143
351
|
const manifestObjectPath = path.posix.join(workDir, "plugin-manifest-exports.o");
|
|
144
352
|
const invokeObjectPath = path.posix.join(workDir, "plugin-invoke-bridge.o");
|
|
145
353
|
const wasmOutputPath = path.posix.join(workDir, "module.wasm");
|
|
@@ -165,6 +373,43 @@ async function compileWithEmception(options = {}) {
|
|
|
165
373
|
"-o",
|
|
166
374
|
sourceObjectPath,
|
|
167
375
|
],
|
|
376
|
+
];
|
|
377
|
+
|
|
378
|
+
for (const command of commands) {
|
|
379
|
+
const result = emception.run(command.join(" "));
|
|
380
|
+
if (result.returncode !== 0) {
|
|
381
|
+
throw new Error(
|
|
382
|
+
`Compilation failed with ${command[0]} (emception): ${result.stderr || result.stdout}`,
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const sourceObjectBytes = new Uint8Array(emception.readFile(sourceObjectPath));
|
|
388
|
+
const guestLink = deriveGuestLinkRenameArgs({
|
|
389
|
+
objectBytes: sourceObjectBytes,
|
|
390
|
+
pluginId: manifest?.pluginId,
|
|
391
|
+
methodIds: Array.isArray(manifest?.methods)
|
|
392
|
+
? manifest.methods.map((method) => String(method?.methodId ?? ""))
|
|
393
|
+
: [],
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
const linkCompileCommand = [
|
|
397
|
+
sourceCompilerCommand,
|
|
398
|
+
"-c",
|
|
399
|
+
sourcePath,
|
|
400
|
+
`-I${workDir}`,
|
|
401
|
+
...guestLink.renameArgs,
|
|
402
|
+
"-o",
|
|
403
|
+
linkObjectPath,
|
|
404
|
+
];
|
|
405
|
+
const linkCompileResult = emception.run(linkCompileCommand.join(" "));
|
|
406
|
+
if (linkCompileResult.returncode !== 0) {
|
|
407
|
+
throw new Error(
|
|
408
|
+
`Compilation failed with ${linkCompileCommand[0]} (emception): ${linkCompileResult.stderr || linkCompileResult.stdout}`,
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const remainingCommands = [
|
|
168
413
|
[
|
|
169
414
|
"em++",
|
|
170
415
|
"-c",
|
|
@@ -195,8 +440,7 @@ async function compileWithEmception(options = {}) {
|
|
|
195
440
|
wasmOutputPath,
|
|
196
441
|
],
|
|
197
442
|
];
|
|
198
|
-
|
|
199
|
-
for (const command of commands) {
|
|
443
|
+
for (const command of remainingCommands) {
|
|
200
444
|
const result = emception.run(command.join(" "));
|
|
201
445
|
if (result.returncode !== 0) {
|
|
202
446
|
throw new Error(
|
|
@@ -206,8 +450,20 @@ async function compileWithEmception(options = {}) {
|
|
|
206
450
|
}
|
|
207
451
|
|
|
208
452
|
const wasmBytes = new Uint8Array(emception.readFile(wasmOutputPath));
|
|
453
|
+
const linkObjectBytes = new Uint8Array(emception.readFile(linkObjectPath));
|
|
209
454
|
await writeFile(resolvedOutputPath, wasmBytes);
|
|
210
|
-
return {
|
|
455
|
+
return {
|
|
456
|
+
wasmBytes,
|
|
457
|
+
outputPath: resolvedOutputPath,
|
|
458
|
+
tempDir,
|
|
459
|
+
guestLink: {
|
|
460
|
+
format: "wasm-object",
|
|
461
|
+
language,
|
|
462
|
+
symbolPrefix: guestLink.prefix,
|
|
463
|
+
methodSymbols: guestLink.methodSymbols,
|
|
464
|
+
objectBytes: linkObjectBytes,
|
|
465
|
+
},
|
|
466
|
+
};
|
|
211
467
|
} finally {
|
|
212
468
|
try {
|
|
213
469
|
removeEmceptionDirectory(emception, workDir);
|
|
@@ -275,6 +531,8 @@ export async function compileModuleFromSource(options = {}) {
|
|
|
275
531
|
noEntry: includeCommandMain !== true,
|
|
276
532
|
};
|
|
277
533
|
const result = await compileWithEmception({
|
|
534
|
+
manifest,
|
|
535
|
+
language: compiler.language,
|
|
278
536
|
sourceCompilerCommand: compiler.command,
|
|
279
537
|
sourceExtension: compiler.extension,
|
|
280
538
|
sourceCode,
|
|
@@ -301,6 +559,7 @@ export async function compileModuleFromSource(options = {}) {
|
|
|
301
559
|
outputPath: resolvedOutputPath,
|
|
302
560
|
tempDir,
|
|
303
561
|
wasmBytes,
|
|
562
|
+
guestLink: result.guestLink,
|
|
304
563
|
manifestWarnings: warnings,
|
|
305
564
|
report,
|
|
306
565
|
};
|
|
@@ -394,12 +653,16 @@ export async function protectModuleArtifact(options = {}) {
|
|
|
394
653
|
|
|
395
654
|
let singleFileBundle = null;
|
|
396
655
|
if (options.singleFileBundle === true) {
|
|
656
|
+
const additionalEntries = [
|
|
657
|
+
...(Array.isArray(options.bundleEntries) ? options.bundleEntries : []),
|
|
658
|
+
...createGuestLinkBundleEntries(options.guestLink),
|
|
659
|
+
];
|
|
397
660
|
singleFileBundle = await createSingleFileBundle({
|
|
398
661
|
wasmBytes,
|
|
399
662
|
manifest,
|
|
400
663
|
authorization: signedAuthorization,
|
|
401
664
|
transportEnvelope: encryptedEnvelope,
|
|
402
|
-
entries:
|
|
665
|
+
entries: additionalEntries,
|
|
403
666
|
});
|
|
404
667
|
}
|
|
405
668
|
|
package/src/deployment/index.js
CHANGED
|
@@ -402,6 +402,9 @@ function buildMethodLookup(manifest) {
|
|
|
402
402
|
}
|
|
403
403
|
|
|
404
404
|
function buildExternalInterfaceLookup(manifest) {
|
|
405
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
405
408
|
const lookup = new Map();
|
|
406
409
|
if (!Array.isArray(manifest?.externalInterfaces)) {
|
|
407
410
|
return lookup;
|
|
@@ -427,6 +430,9 @@ function validateDeclaredInterface(
|
|
|
427
430
|
externalInterfaceLookup,
|
|
428
431
|
allowedDirections,
|
|
429
432
|
) {
|
|
433
|
+
if (!externalInterfaceLookup) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
430
436
|
const normalizedInterfaceId = normalizeString(interfaceId);
|
|
431
437
|
if (!normalizedInterfaceId) {
|
|
432
438
|
return;
|
package/src/index.d.ts
CHANGED
|
@@ -424,10 +424,19 @@ export interface CompilationResult {
|
|
|
424
424
|
outputPath: string | null;
|
|
425
425
|
tempDir: string | null;
|
|
426
426
|
wasmBytes: Uint8Array;
|
|
427
|
+
guestLink: GuestLinkArtifact | null;
|
|
427
428
|
manifestWarnings: string[];
|
|
428
429
|
report: ComplianceReport;
|
|
429
430
|
}
|
|
430
431
|
|
|
432
|
+
export interface GuestLinkArtifact {
|
|
433
|
+
format: "wasm-object";
|
|
434
|
+
language: string;
|
|
435
|
+
symbolPrefix: string;
|
|
436
|
+
methodSymbols: Record<string, string>;
|
|
437
|
+
objectBytes: Uint8Array;
|
|
438
|
+
}
|
|
439
|
+
|
|
431
440
|
export interface ProtectedArtifact {
|
|
432
441
|
mnemonic: string;
|
|
433
442
|
signingPublicKeyHex: string;
|
|
@@ -473,7 +482,8 @@ export function protectModuleArtifact(options: {
|
|
|
473
482
|
targetUrl?: string;
|
|
474
483
|
capabilities?: string[];
|
|
475
484
|
singleFileBundle?: boolean;
|
|
476
|
-
bundleEntries?: Record<string, unknown
|
|
485
|
+
bundleEntries?: Array<Record<string, unknown>>;
|
|
486
|
+
guestLink?: GuestLinkArtifact | null;
|
|
477
487
|
}): Promise<ProtectedArtifact>;
|
|
478
488
|
|
|
479
489
|
export function createRecipientKeypairHex(): Promise<{
|
|
@@ -567,6 +577,10 @@ export function validateManifestAgainstStandardsCatalog(
|
|
|
567
577
|
|
|
568
578
|
export const SDS_BUNDLE_SECTION_NAME: string;
|
|
569
579
|
export const DEFAULT_HASH_ALGORITHM: string;
|
|
580
|
+
export const SDS_GUEST_LINK_OBJECT_ENTRY_ID: string;
|
|
581
|
+
export const SDS_GUEST_LINK_METADATA_ENTRY_ID: string;
|
|
582
|
+
export const SDS_GUEST_LINK_SECTION_NAME: string;
|
|
583
|
+
export const SDS_GUEST_LINK_MEDIA_TYPE: string;
|
|
570
584
|
|
|
571
585
|
export function createSingleFileBundle(options: {
|
|
572
586
|
wasmBytes: Uint8Array;
|