space-data-module-sdk 0.2.0 → 0.2.6
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/README.md +77 -2
- package/package.json +13 -4
- package/schemas/PluginInvokeRequest.fbs +18 -0
- package/schemas/PluginInvokeResponse.fbs +30 -0
- package/schemas/PluginManifest.fbs +7 -0
- package/schemas/TypedArenaBuffer.fbs +23 -2
- package/src/bundle/codec.js +24 -0
- package/src/compiler/compileModule.js +182 -143
- package/src/compiler/emception.d.ts +60 -0
- package/src/compiler/emception.js +191 -0
- package/src/compiler/emceptionNode.js +234 -0
- package/src/compiler/flatcSupport.js +66 -0
- package/src/compiler/index.d.ts +24 -0
- package/src/compiler/index.js +5 -0
- package/src/compiler/invokeGlue.js +884 -0
- package/src/compliance/pluginCompliance.js +241 -1
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts +51 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.js +131 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.js.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.ts +173 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts +76 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.js +184 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.js.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.ts +243 -0
- package/src/generated/orbpro/invoke.d.ts +3 -0
- package/src/generated/orbpro/invoke.d.ts.map +1 -0
- package/src/generated/orbpro/invoke.js +5 -0
- package/src/generated/orbpro/invoke.js.map +1 -0
- package/src/generated/orbpro/invoke.ts +6 -0
- package/src/generated/orbpro/manifest/accepted-type-set.d.ts +4 -4
- package/src/generated/orbpro/manifest/accepted-type-set.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/accepted-type-set.js +18 -11
- package/src/generated/orbpro/manifest/accepted-type-set.js.map +1 -1
- package/src/generated/orbpro/manifest/build-artifact.d.ts +1 -1
- package/src/generated/orbpro/manifest/build-artifact.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/build-artifact.js +28 -15
- package/src/generated/orbpro/manifest/build-artifact.js.map +1 -1
- package/src/generated/orbpro/manifest/capability-kind.d.ts +1 -1
- package/src/generated/orbpro/manifest/capability-kind.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/capability-kind.js +1 -1
- package/src/generated/orbpro/manifest/capability-kind.js.map +1 -1
- package/src/generated/orbpro/manifest/drain-policy.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/drain-policy.js.map +1 -1
- package/src/generated/orbpro/manifest/host-capability.d.ts +2 -2
- package/src/generated/orbpro/manifest/host-capability.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/host-capability.js +19 -11
- package/src/generated/orbpro/manifest/host-capability.js.map +1 -1
- package/src/generated/orbpro/manifest/invoke-surface.d.ts +8 -0
- package/src/generated/orbpro/manifest/invoke-surface.d.ts.map +1 -0
- package/src/generated/orbpro/manifest/invoke-surface.js +11 -0
- package/src/generated/orbpro/manifest/invoke-surface.js.map +1 -0
- package/src/generated/orbpro/manifest/invoke-surface.ts +11 -0
- package/src/generated/orbpro/manifest/method-manifest.d.ts +6 -6
- package/src/generated/orbpro/manifest/method-manifest.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/method-manifest.js +33 -16
- package/src/generated/orbpro/manifest/method-manifest.js.map +1 -1
- package/src/generated/orbpro/manifest/plugin-family.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/plugin-family.js.map +1 -1
- package/src/generated/orbpro/manifest/plugin-manifest.d.ts +10 -2
- package/src/generated/orbpro/manifest/plugin-manifest.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/plugin-manifest.js +48 -9
- package/src/generated/orbpro/manifest/plugin-manifest.js.map +1 -1
- package/src/generated/orbpro/manifest/plugin-manifest.ts +322 -491
- package/src/generated/orbpro/manifest/port-manifest.d.ts +4 -4
- package/src/generated/orbpro/manifest/port-manifest.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/port-manifest.js +26 -13
- package/src/generated/orbpro/manifest/port-manifest.js.map +1 -1
- package/src/generated/orbpro/manifest/protocol-spec.d.ts +1 -1
- package/src/generated/orbpro/manifest/protocol-spec.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/protocol-spec.js +28 -15
- package/src/generated/orbpro/manifest/protocol-spec.js.map +1 -1
- package/src/generated/orbpro/manifest/timer-spec.d.ts +1 -1
- package/src/generated/orbpro/manifest/timer-spec.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/timer-spec.js +27 -16
- package/src/generated/orbpro/manifest/timer-spec.js.map +1 -1
- package/src/generated/orbpro/manifest.d.ts +13 -0
- package/src/generated/orbpro/manifest.d.ts.map +1 -0
- package/src/generated/orbpro/manifest.js +1 -0
- package/src/generated/orbpro/manifest.js.map +1 -0
- package/src/generated/orbpro/manifest.ts +16 -0
- package/src/generated/orbpro/stream/buffer-mutability.d.ts.map +1 -1
- package/src/generated/orbpro/stream/buffer-mutability.js.map +1 -1
- package/src/generated/orbpro/stream/buffer-ownership.d.ts.map +1 -1
- package/src/generated/orbpro/stream/buffer-ownership.js.map +1 -1
- package/src/generated/orbpro/stream/flat-buffer-type-ref.d.ts +22 -5
- package/src/generated/orbpro/stream/flat-buffer-type-ref.d.ts.map +1 -1
- package/src/generated/orbpro/stream/flat-buffer-type-ref.js +107 -17
- package/src/generated/orbpro/stream/flat-buffer-type-ref.js.map +1 -1
- package/src/generated/orbpro/stream/flat-buffer-type-ref.ts +126 -2
- package/src/generated/orbpro/stream/payload-wire-format.d.ts +8 -0
- package/src/generated/orbpro/stream/payload-wire-format.d.ts.map +1 -0
- package/src/generated/orbpro/stream/payload-wire-format.js +11 -0
- package/src/generated/orbpro/stream/payload-wire-format.js.map +1 -0
- package/src/generated/orbpro/stream/payload-wire-format.ts +11 -0
- package/src/generated/orbpro/stream/typed-arena-buffer.d.ts +4 -4
- package/src/generated/orbpro/stream/typed-arena-buffer.d.ts.map +1 -1
- package/src/generated/orbpro/stream/typed-arena-buffer.js +42 -24
- package/src/generated/orbpro/stream/typed-arena-buffer.js.map +1 -1
- package/src/index.d.ts +96 -5
- package/src/index.js +3 -0
- package/src/invoke/codec.js +278 -0
- package/src/invoke/index.js +9 -0
- package/src/manifest/codec.js +10 -2
- package/src/manifest/index.js +5 -2
- package/src/manifest/normalize.js +58 -0
- package/src/runtime/constants.js +12 -0
- package/src/runtime/index.d.ts +13 -0
- package/src/runtime/index.js +2 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { cp, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const PATCH_VERSION = "space-data-module-sdk-emception-node-v1";
|
|
10
|
+
const PATCH_MARKER_FILENAME = ".space-data-module-sdk-emception-patch";
|
|
11
|
+
const EMCEPTION_PATCH_ROOT = path.join(
|
|
12
|
+
os.tmpdir(),
|
|
13
|
+
`space-data-module-sdk-emception-node-${process.pid}`,
|
|
14
|
+
);
|
|
15
|
+
const FILE_URL_FETCH_PATCH_FLAG =
|
|
16
|
+
"__spaceDataModuleSdkFileUrlFetchPatched";
|
|
17
|
+
|
|
18
|
+
let patchedEmceptionRootPromise = null;
|
|
19
|
+
|
|
20
|
+
function installNodeRuntimeShims() {
|
|
21
|
+
if (typeof globalThis.require !== "function") {
|
|
22
|
+
globalThis.require = require;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!globalThis.XMLHttpRequest) {
|
|
26
|
+
class FileUrlXMLHttpRequest {
|
|
27
|
+
open(method, url, async = true) {
|
|
28
|
+
this.method = method;
|
|
29
|
+
this.url = url;
|
|
30
|
+
this.async = async;
|
|
31
|
+
this.status = 0;
|
|
32
|
+
this.response = null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
overrideMimeType() {}
|
|
36
|
+
|
|
37
|
+
send() {
|
|
38
|
+
if (this.async) {
|
|
39
|
+
throw new Error("Async file XMLHttpRequest is not supported.");
|
|
40
|
+
}
|
|
41
|
+
const target =
|
|
42
|
+
typeof this.url === "string" && this.url.startsWith("file:")
|
|
43
|
+
? new URL(this.url)
|
|
44
|
+
: this.url;
|
|
45
|
+
const data = readFileSync(target);
|
|
46
|
+
this.status = 200;
|
|
47
|
+
this.response = data.buffer.slice(
|
|
48
|
+
data.byteOffset,
|
|
49
|
+
data.byteOffset + data.byteLength,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
globalThis.XMLHttpRequest = FileUrlXMLHttpRequest;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!globalThis[FILE_URL_FETCH_PATCH_FLAG]) {
|
|
58
|
+
const originalFetch = globalThis.fetch;
|
|
59
|
+
globalThis.fetch = async (input, init) => {
|
|
60
|
+
const url =
|
|
61
|
+
typeof input === "string"
|
|
62
|
+
? input
|
|
63
|
+
: input?.url ?? String(input);
|
|
64
|
+
if (!url.startsWith("file:")) {
|
|
65
|
+
if (typeof originalFetch !== "function") {
|
|
66
|
+
throw new Error("fetch is not available for non-file URLs.");
|
|
67
|
+
}
|
|
68
|
+
return originalFetch(input, init);
|
|
69
|
+
}
|
|
70
|
+
const bytes = await readFile(new URL(url));
|
|
71
|
+
return {
|
|
72
|
+
ok: true,
|
|
73
|
+
status: 200,
|
|
74
|
+
url,
|
|
75
|
+
async arrayBuffer() {
|
|
76
|
+
return bytes.buffer.slice(
|
|
77
|
+
bytes.byteOffset,
|
|
78
|
+
bytes.byteOffset + bytes.byteLength,
|
|
79
|
+
);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
globalThis[FILE_URL_FETCH_PATCH_FLAG] = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function patchEmceptionModuleTree(rootDir) {
|
|
88
|
+
const entries = await readdir(rootDir, { withFileTypes: true });
|
|
89
|
+
for (const entry of entries) {
|
|
90
|
+
const fullPath = path.join(rootDir, entry.name);
|
|
91
|
+
if (entry.isDirectory()) {
|
|
92
|
+
await patchEmceptionModuleTree(fullPath);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (!entry.name.endsWith(".mjs")) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let source = await readFile(fullPath, "utf8");
|
|
100
|
+
source = source.replaceAll(
|
|
101
|
+
'scriptDirectory=__dirname+"/"',
|
|
102
|
+
'scriptDirectory=(new URL(".", import.meta.url)).pathname',
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
if (entry.name === "emception.mjs") {
|
|
106
|
+
source = source.replace(
|
|
107
|
+
"this.#fs = await new FileSystem();",
|
|
108
|
+
[
|
|
109
|
+
"this.#fs = await new FileSystem({",
|
|
110
|
+
" locateFile: (file, scriptDirectory) => scriptDirectory + file,",
|
|
111
|
+
' cache: "/tmp/emception-cache",',
|
|
112
|
+
" });",
|
|
113
|
+
].join("\n"),
|
|
114
|
+
);
|
|
115
|
+
source = source.replace(
|
|
116
|
+
"const config = {",
|
|
117
|
+
[
|
|
118
|
+
"const config = {",
|
|
119
|
+
" locateFile: (file, scriptDirectory) => scriptDirectory + file,",
|
|
120
|
+
].join("\n"),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (entry.name === "FileSystem.mjs") {
|
|
125
|
+
source = source.replace(
|
|
126
|
+
[
|
|
127
|
+
" if (!this.exists(cache)) {",
|
|
128
|
+
" this.persist(cache);",
|
|
129
|
+
" }",
|
|
130
|
+
" await this.pull();",
|
|
131
|
+
].join("\n"),
|
|
132
|
+
[
|
|
133
|
+
' if (typeof indexedDB !== "undefined") {',
|
|
134
|
+
" if (!this.exists(cache)) {",
|
|
135
|
+
" this.persist(cache);",
|
|
136
|
+
" }",
|
|
137
|
+
" await this.pull();",
|
|
138
|
+
" }",
|
|
139
|
+
].join("\n"),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
await writeFile(fullPath, source, "utf8");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function preparePatchedEmceptionRoot() {
|
|
148
|
+
if (!patchedEmceptionRootPromise) {
|
|
149
|
+
patchedEmceptionRootPromise = (async () => {
|
|
150
|
+
const sourceRoot = path.dirname(require.resolve("sdn-emception"));
|
|
151
|
+
const markerPath = path.join(EMCEPTION_PATCH_ROOT, PATCH_MARKER_FILENAME);
|
|
152
|
+
let marker = null;
|
|
153
|
+
try {
|
|
154
|
+
marker = await readFile(markerPath, "utf8");
|
|
155
|
+
} catch {
|
|
156
|
+
marker = null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (marker?.trim() !== PATCH_VERSION) {
|
|
160
|
+
await rm(EMCEPTION_PATCH_ROOT, { recursive: true, force: true });
|
|
161
|
+
await cp(sourceRoot, EMCEPTION_PATCH_ROOT, { recursive: true });
|
|
162
|
+
await patchEmceptionModuleTree(EMCEPTION_PATCH_ROOT);
|
|
163
|
+
await writeFile(markerPath, `${PATCH_VERSION}\n`, "utf8");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return EMCEPTION_PATCH_ROOT;
|
|
167
|
+
})().catch((error) => {
|
|
168
|
+
patchedEmceptionRootPromise = null;
|
|
169
|
+
throw error;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return patchedEmceptionRootPromise;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
class EmceptionController {
|
|
177
|
+
#instancePromise = null;
|
|
178
|
+
#executionQueue = Promise.resolve();
|
|
179
|
+
|
|
180
|
+
async load() {
|
|
181
|
+
if (!this.#instancePromise) {
|
|
182
|
+
this.#instancePromise = (async () => {
|
|
183
|
+
installNodeRuntimeShims();
|
|
184
|
+
const patchedRoot = await preparePatchedEmceptionRoot();
|
|
185
|
+
const moduleUrl = pathToFileURL(path.join(patchedRoot, "emception.mjs")).href;
|
|
186
|
+
const { default: Emception } = await import(moduleUrl);
|
|
187
|
+
const emception = new Emception({
|
|
188
|
+
baseUrl: pathToFileURL(`${patchedRoot}${path.sep}`).href,
|
|
189
|
+
});
|
|
190
|
+
await emception.init();
|
|
191
|
+
return emception;
|
|
192
|
+
})().catch((error) => {
|
|
193
|
+
this.#instancePromise = null;
|
|
194
|
+
throw error;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return this.#instancePromise;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async withLock(task) {
|
|
202
|
+
const previous = this.#executionQueue;
|
|
203
|
+
let release = () => {};
|
|
204
|
+
this.#executionQueue = new Promise((resolve) => {
|
|
205
|
+
release = resolve;
|
|
206
|
+
});
|
|
207
|
+
await previous.catch(() => {});
|
|
208
|
+
try {
|
|
209
|
+
const emception = await this.load().catch((error) => {
|
|
210
|
+
if (!error.code) {
|
|
211
|
+
error.code = "EMCEPTION_LOAD_FAILED";
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
});
|
|
215
|
+
return await task(emception);
|
|
216
|
+
} finally {
|
|
217
|
+
release();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const sharedEmceptionController = new EmceptionController();
|
|
223
|
+
|
|
224
|
+
export function getSharedEmceptionController() {
|
|
225
|
+
return sharedEmceptionController;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export async function loadEmception() {
|
|
229
|
+
return sharedEmceptionController.load();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export async function runWithEmceptionLock(task) {
|
|
233
|
+
return sharedEmceptionController.withLock(task);
|
|
234
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
import { FlatcRunner } from "flatc-wasm";
|
|
6
|
+
|
|
7
|
+
const SDK_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
8
|
+
const SCHEMA_DIR = path.join(SDK_ROOT, "schemas");
|
|
9
|
+
|
|
10
|
+
let flatcRunnerPromise = null;
|
|
11
|
+
let flatbuffersCppRuntimeHeadersPromise = null;
|
|
12
|
+
let invokeCppSchemaHeadersPromise = null;
|
|
13
|
+
|
|
14
|
+
function loadFlatcRunner() {
|
|
15
|
+
if (!flatcRunnerPromise) {
|
|
16
|
+
flatcRunnerPromise = FlatcRunner.init();
|
|
17
|
+
}
|
|
18
|
+
return flatcRunnerPromise;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function loadInvokeSchemaFiles() {
|
|
22
|
+
const filenames = [
|
|
23
|
+
"TypedArenaBuffer.fbs",
|
|
24
|
+
"PluginInvokeRequest.fbs",
|
|
25
|
+
"PluginInvokeResponse.fbs",
|
|
26
|
+
];
|
|
27
|
+
const entries = await Promise.all(
|
|
28
|
+
filenames.map(async (filename) => [
|
|
29
|
+
`/schemas/${filename}`,
|
|
30
|
+
await readFile(path.join(SCHEMA_DIR, filename), "utf8"),
|
|
31
|
+
]),
|
|
32
|
+
);
|
|
33
|
+
return Object.fromEntries(entries);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function getFlatbuffersCppRuntimeHeaders() {
|
|
37
|
+
if (!flatbuffersCppRuntimeHeadersPromise) {
|
|
38
|
+
flatbuffersCppRuntimeHeadersPromise = (async () => {
|
|
39
|
+
const flatc = await loadFlatcRunner();
|
|
40
|
+
return flatc.getEmbeddedRuntime("cpp");
|
|
41
|
+
})();
|
|
42
|
+
}
|
|
43
|
+
return flatbuffersCppRuntimeHeadersPromise;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function getInvokeCppSchemaHeaders() {
|
|
47
|
+
if (!invokeCppSchemaHeadersPromise) {
|
|
48
|
+
invokeCppSchemaHeadersPromise = (async () => {
|
|
49
|
+
const flatc = await loadFlatcRunner();
|
|
50
|
+
const schemaFiles = await loadInvokeSchemaFiles();
|
|
51
|
+
const generatedHeaders = {};
|
|
52
|
+
for (const entry of Object.keys(schemaFiles)) {
|
|
53
|
+
Object.assign(
|
|
54
|
+
generatedHeaders,
|
|
55
|
+
flatc.generateCode(
|
|
56
|
+
{ entry, files: schemaFiles },
|
|
57
|
+
"cpp",
|
|
58
|
+
{ genObjectApi: true },
|
|
59
|
+
),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return generatedHeaders;
|
|
63
|
+
})();
|
|
64
|
+
}
|
|
65
|
+
return invokeCppSchemaHeadersPromise;
|
|
66
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
CompilationResult,
|
|
3
|
+
ProtectedArtifact,
|
|
4
|
+
} from "../index.js";
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
cleanupCompilation,
|
|
8
|
+
compileModuleFromSource,
|
|
9
|
+
createRecipientKeypairHex,
|
|
10
|
+
protectModuleArtifact,
|
|
11
|
+
} from "../index.js";
|
|
12
|
+
|
|
13
|
+
export type {
|
|
14
|
+
EmceptionCommandResult,
|
|
15
|
+
SharedEmceptionFileContent,
|
|
16
|
+
SharedEmceptionHandle,
|
|
17
|
+
SharedEmceptionSession,
|
|
18
|
+
} from "./emception.js";
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
createSharedEmceptionSession,
|
|
22
|
+
loadSharedEmception,
|
|
23
|
+
withSharedEmception,
|
|
24
|
+
} from "./emception.js";
|