@kaleabdenbel/llmweb 1.0.2 → 1.0.3
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 +1 -0
- package/dist/adapters/express.js +17 -7
- package/dist/adapters/express.mjs +131 -3
- package/dist/adapters/next.js +17 -7
- package/dist/adapters/next.mjs +131 -3
- package/dist/adapters/react.js +77 -15
- package/dist/adapters/react.mjs +182 -4
- package/dist/adapters/vanilla.js +17 -7
- package/dist/adapters/vanilla.mjs +131 -3
- package/dist/index.browser.js +175 -0
- package/dist/{chunk-HRF6I6KB.mjs → index.browser.mjs} +26 -21
- package/dist/index.js +29 -19
- package/dist/index.mjs +143 -6
- package/package.json +5 -3
- package/dist/adapters/express.d.ts +0 -5
- package/dist/adapters/next.d.ts +0 -18
- package/dist/adapters/react.d.ts +0 -15
- package/dist/adapters/vanilla.d.ts +0 -5
- package/dist/core/injector.d.ts +0 -11
- package/dist/core/merger.d.ts +0 -7
- package/dist/core/resolver.d.ts +0 -12
- package/dist/core/transformer.d.ts +0 -7
- package/dist/index.d.ts +0 -8
- package/dist/types/index.d.ts +0 -23
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ The data compiler that transforms messy application state into LLM-readable trut
|
|
|
9
9
|
- **Static Truth**: Your contract with the world. Deterministic. Versioned.
|
|
10
10
|
- **Dynamic Truth**: Live data from APIs, Server Actions, or DB calls.
|
|
11
11
|
- **The Engine**: Compiles these into a single, structured JSON object for LLMs.
|
|
12
|
+
- **Framework Adapters**: Utilities for [Next.js](docs/next.md), [React](docs/react.md), [Express](docs/express.md), and [Vanilla JS](docs/vanilla.md).
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
package/dist/adapters/express.js
CHANGED
|
@@ -103,16 +103,15 @@ function merge(staticData, dynamicResults) {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
// src/
|
|
107
|
-
|
|
108
|
-
var import_node_path = require("path");
|
|
109
|
-
async function createLLMSource(config, options = {}) {
|
|
106
|
+
// src/core/compiler.ts
|
|
107
|
+
async function compileLLM(config, loader, options = {}) {
|
|
110
108
|
let staticTruth = {};
|
|
111
109
|
if (config.static) {
|
|
112
110
|
try {
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
const content = await loader(config.static);
|
|
112
|
+
if (content) {
|
|
113
|
+
staticTruth = JSON.parse(content);
|
|
114
|
+
}
|
|
116
115
|
} catch (error) {
|
|
117
116
|
if (options.failLoudly) {
|
|
118
117
|
throw new Error(`[llmweb] Static Truth Error: Failed to load/parse JSON at ${config.static}. ${error}`);
|
|
@@ -146,6 +145,17 @@ async function createLLMSource(config, options = {}) {
|
|
|
146
145
|
return merge(staticTruth, dynamicTruth);
|
|
147
146
|
}
|
|
148
147
|
|
|
148
|
+
// src/index.ts
|
|
149
|
+
var import_node_fs = require("fs");
|
|
150
|
+
var import_node_path = require("path");
|
|
151
|
+
var nodeLoader = async (path) => {
|
|
152
|
+
const fullPath = path.startsWith("/") ? path : (0, import_node_path.join)(process.cwd(), path);
|
|
153
|
+
return (0, import_node_fs.readFileSync)(fullPath, "utf-8");
|
|
154
|
+
};
|
|
155
|
+
async function createLLMSource(config, options = {}) {
|
|
156
|
+
return compileLLM(config, nodeLoader, options);
|
|
157
|
+
}
|
|
158
|
+
|
|
149
159
|
// src/adapters/express.ts
|
|
150
160
|
function llmMiddleware(config) {
|
|
151
161
|
return async (req, res, next) => {
|
|
@@ -1,6 +1,134 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/core/resolver.ts
|
|
2
|
+
async function resolveAll(dynamicSources, options = {}) {
|
|
3
|
+
const keys = Object.keys(dynamicSources);
|
|
4
|
+
const results = await Promise.allSettled(
|
|
5
|
+
keys.map((key) => resolveSource(dynamicSources[key], options.timeout))
|
|
6
|
+
);
|
|
7
|
+
const data = {};
|
|
8
|
+
results.forEach((result, index) => {
|
|
9
|
+
const key = keys[index];
|
|
10
|
+
if (result.status === "fulfilled") {
|
|
11
|
+
data[key] = result.value;
|
|
12
|
+
} else {
|
|
13
|
+
console.error(`[llmweb] Failed to resolve source "${key}":`, result.reason);
|
|
14
|
+
data[key] = null;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return data;
|
|
18
|
+
}
|
|
19
|
+
async function resolveSource(source, timeoutMs) {
|
|
20
|
+
const { from } = source;
|
|
21
|
+
const controller = timeoutMs ? new AbortController() : null;
|
|
22
|
+
const signal = controller?.signal;
|
|
23
|
+
const timeoutPromise = timeoutMs ? new Promise(
|
|
24
|
+
(_, reject) => setTimeout(() => {
|
|
25
|
+
controller?.abort();
|
|
26
|
+
reject(new Error(`Timeout of ${timeoutMs}ms exceeded`));
|
|
27
|
+
}, timeoutMs)
|
|
28
|
+
) : null;
|
|
29
|
+
const resolvePromise = (async () => {
|
|
30
|
+
if (from.type === "fetch") {
|
|
31
|
+
if (!from.url) throw new Error("Fetch source requires a URL");
|
|
32
|
+
const response = await fetch(from.url, { signal });
|
|
33
|
+
if (!response.ok) throw new Error(`HTTP error ${response.status} for ${from.url}`);
|
|
34
|
+
return response.json();
|
|
35
|
+
}
|
|
36
|
+
if (from.type === "fn") {
|
|
37
|
+
if (!from.call) throw new Error('Function source requires a "call" property');
|
|
38
|
+
return from.call();
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Unsupported source type: ${from.type}`);
|
|
41
|
+
})();
|
|
42
|
+
if (timeoutPromise) {
|
|
43
|
+
return Promise.race([resolvePromise, timeoutPromise]);
|
|
44
|
+
}
|
|
45
|
+
return resolvePromise;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/core/transformer.ts
|
|
49
|
+
function transform(sourceData, schema) {
|
|
50
|
+
if (!sourceData) return sourceData;
|
|
51
|
+
if (Array.isArray(sourceData)) {
|
|
52
|
+
return sourceData.map((item) => transform(item, schema));
|
|
53
|
+
}
|
|
54
|
+
if (typeof sourceData !== "object") return sourceData;
|
|
55
|
+
const result = {};
|
|
56
|
+
for (const [targetKey, mapping] of Object.entries(schema)) {
|
|
57
|
+
if (typeof mapping === "string") {
|
|
58
|
+
result[targetKey] = getValueByPath(sourceData, mapping);
|
|
59
|
+
} else if (typeof mapping === "function") {
|
|
60
|
+
result[targetKey] = mapping(sourceData);
|
|
61
|
+
} else if (typeof mapping === "object" && mapping !== null) {
|
|
62
|
+
result[targetKey] = transform(sourceData, mapping);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
function getValueByPath(obj, path) {
|
|
68
|
+
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/core/merger.ts
|
|
72
|
+
function merge(staticData, dynamicResults) {
|
|
73
|
+
if (!staticData) return dynamicResults;
|
|
74
|
+
return {
|
|
75
|
+
...staticData,
|
|
76
|
+
...dynamicResults
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/core/compiler.ts
|
|
81
|
+
async function compileLLM(config, loader, options = {}) {
|
|
82
|
+
let staticTruth = {};
|
|
83
|
+
if (config.static) {
|
|
84
|
+
try {
|
|
85
|
+
const content = await loader(config.static);
|
|
86
|
+
if (content) {
|
|
87
|
+
staticTruth = JSON.parse(content);
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (options.failLoudly) {
|
|
91
|
+
throw new Error(`[llmweb] Static Truth Error: Failed to load/parse JSON at ${config.static}. ${error}`);
|
|
92
|
+
}
|
|
93
|
+
console.warn(`[llmweb] Warning: Could not load static JSON at ${config.static}. Proceeding with dynamic data only.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const dynamicTruth = {};
|
|
97
|
+
if (config.dynamic) {
|
|
98
|
+
const rawResults = await resolveAll(config.dynamic, { timeout: options.timeout });
|
|
99
|
+
for (const [key, source] of Object.entries(config.dynamic)) {
|
|
100
|
+
const rawData = rawResults[key];
|
|
101
|
+
if (rawData === null && options.failLoudly) {
|
|
102
|
+
throw new Error(`[llmweb] Dynamic Truth Error: Source "${key}" failed to resolve.`);
|
|
103
|
+
}
|
|
104
|
+
if (rawData && source.map) {
|
|
105
|
+
try {
|
|
106
|
+
dynamicTruth[key] = transform(rawData, source.map);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (options.failLoudly) {
|
|
109
|
+
throw new Error(`[llmweb] Transformation Error: Failed to map source "${key}". ${error}`);
|
|
110
|
+
}
|
|
111
|
+
console.error(`[llmweb] Warning: Mapping failed for "${key}". Using raw data.`);
|
|
112
|
+
dynamicTruth[key] = rawData;
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
dynamicTruth[key] = rawData;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return merge(staticTruth, dynamicTruth);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/index.ts
|
|
123
|
+
import { readFileSync } from "fs";
|
|
124
|
+
import { join } from "path";
|
|
125
|
+
var nodeLoader = async (path) => {
|
|
126
|
+
const fullPath = path.startsWith("/") ? path : join(process.cwd(), path);
|
|
127
|
+
return readFileSync(fullPath, "utf-8");
|
|
128
|
+
};
|
|
129
|
+
async function createLLMSource(config, options = {}) {
|
|
130
|
+
return compileLLM(config, nodeLoader, options);
|
|
131
|
+
}
|
|
4
132
|
|
|
5
133
|
// src/adapters/express.ts
|
|
6
134
|
function llmMiddleware(config) {
|
package/dist/adapters/next.js
CHANGED
|
@@ -104,16 +104,15 @@ function merge(staticData, dynamicResults) {
|
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
// src/
|
|
108
|
-
|
|
109
|
-
var import_node_path = require("path");
|
|
110
|
-
async function createLLMSource(config, options = {}) {
|
|
107
|
+
// src/core/compiler.ts
|
|
108
|
+
async function compileLLM(config, loader, options = {}) {
|
|
111
109
|
let staticTruth = {};
|
|
112
110
|
if (config.static) {
|
|
113
111
|
try {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
const content = await loader(config.static);
|
|
113
|
+
if (content) {
|
|
114
|
+
staticTruth = JSON.parse(content);
|
|
115
|
+
}
|
|
117
116
|
} catch (error) {
|
|
118
117
|
if (options.failLoudly) {
|
|
119
118
|
throw new Error(`[llmweb] Static Truth Error: Failed to load/parse JSON at ${config.static}. ${error}`);
|
|
@@ -147,6 +146,17 @@ async function createLLMSource(config, options = {}) {
|
|
|
147
146
|
return merge(staticTruth, dynamicTruth);
|
|
148
147
|
}
|
|
149
148
|
|
|
149
|
+
// src/index.ts
|
|
150
|
+
var import_node_fs = require("fs");
|
|
151
|
+
var import_node_path = require("path");
|
|
152
|
+
var nodeLoader = async (path) => {
|
|
153
|
+
const fullPath = path.startsWith("/") ? path : (0, import_node_path.join)(process.cwd(), path);
|
|
154
|
+
return (0, import_node_fs.readFileSync)(fullPath, "utf-8");
|
|
155
|
+
};
|
|
156
|
+
async function createLLMSource(config, options = {}) {
|
|
157
|
+
return compileLLM(config, nodeLoader, options);
|
|
158
|
+
}
|
|
159
|
+
|
|
150
160
|
// src/adapters/next.tsx
|
|
151
161
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
152
162
|
async function LLMJson({ config, className }) {
|
package/dist/adapters/next.mjs
CHANGED
|
@@ -1,6 +1,134 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/core/resolver.ts
|
|
2
|
+
async function resolveAll(dynamicSources, options = {}) {
|
|
3
|
+
const keys = Object.keys(dynamicSources);
|
|
4
|
+
const results = await Promise.allSettled(
|
|
5
|
+
keys.map((key) => resolveSource(dynamicSources[key], options.timeout))
|
|
6
|
+
);
|
|
7
|
+
const data = {};
|
|
8
|
+
results.forEach((result, index) => {
|
|
9
|
+
const key = keys[index];
|
|
10
|
+
if (result.status === "fulfilled") {
|
|
11
|
+
data[key] = result.value;
|
|
12
|
+
} else {
|
|
13
|
+
console.error(`[llmweb] Failed to resolve source "${key}":`, result.reason);
|
|
14
|
+
data[key] = null;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return data;
|
|
18
|
+
}
|
|
19
|
+
async function resolveSource(source, timeoutMs) {
|
|
20
|
+
const { from } = source;
|
|
21
|
+
const controller = timeoutMs ? new AbortController() : null;
|
|
22
|
+
const signal = controller?.signal;
|
|
23
|
+
const timeoutPromise = timeoutMs ? new Promise(
|
|
24
|
+
(_, reject) => setTimeout(() => {
|
|
25
|
+
controller?.abort();
|
|
26
|
+
reject(new Error(`Timeout of ${timeoutMs}ms exceeded`));
|
|
27
|
+
}, timeoutMs)
|
|
28
|
+
) : null;
|
|
29
|
+
const resolvePromise = (async () => {
|
|
30
|
+
if (from.type === "fetch") {
|
|
31
|
+
if (!from.url) throw new Error("Fetch source requires a URL");
|
|
32
|
+
const response = await fetch(from.url, { signal });
|
|
33
|
+
if (!response.ok) throw new Error(`HTTP error ${response.status} for ${from.url}`);
|
|
34
|
+
return response.json();
|
|
35
|
+
}
|
|
36
|
+
if (from.type === "fn") {
|
|
37
|
+
if (!from.call) throw new Error('Function source requires a "call" property');
|
|
38
|
+
return from.call();
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Unsupported source type: ${from.type}`);
|
|
41
|
+
})();
|
|
42
|
+
if (timeoutPromise) {
|
|
43
|
+
return Promise.race([resolvePromise, timeoutPromise]);
|
|
44
|
+
}
|
|
45
|
+
return resolvePromise;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/core/transformer.ts
|
|
49
|
+
function transform(sourceData, schema) {
|
|
50
|
+
if (!sourceData) return sourceData;
|
|
51
|
+
if (Array.isArray(sourceData)) {
|
|
52
|
+
return sourceData.map((item) => transform(item, schema));
|
|
53
|
+
}
|
|
54
|
+
if (typeof sourceData !== "object") return sourceData;
|
|
55
|
+
const result = {};
|
|
56
|
+
for (const [targetKey, mapping] of Object.entries(schema)) {
|
|
57
|
+
if (typeof mapping === "string") {
|
|
58
|
+
result[targetKey] = getValueByPath(sourceData, mapping);
|
|
59
|
+
} else if (typeof mapping === "function") {
|
|
60
|
+
result[targetKey] = mapping(sourceData);
|
|
61
|
+
} else if (typeof mapping === "object" && mapping !== null) {
|
|
62
|
+
result[targetKey] = transform(sourceData, mapping);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
function getValueByPath(obj, path) {
|
|
68
|
+
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/core/merger.ts
|
|
72
|
+
function merge(staticData, dynamicResults) {
|
|
73
|
+
if (!staticData) return dynamicResults;
|
|
74
|
+
return {
|
|
75
|
+
...staticData,
|
|
76
|
+
...dynamicResults
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/core/compiler.ts
|
|
81
|
+
async function compileLLM(config, loader, options = {}) {
|
|
82
|
+
let staticTruth = {};
|
|
83
|
+
if (config.static) {
|
|
84
|
+
try {
|
|
85
|
+
const content = await loader(config.static);
|
|
86
|
+
if (content) {
|
|
87
|
+
staticTruth = JSON.parse(content);
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (options.failLoudly) {
|
|
91
|
+
throw new Error(`[llmweb] Static Truth Error: Failed to load/parse JSON at ${config.static}. ${error}`);
|
|
92
|
+
}
|
|
93
|
+
console.warn(`[llmweb] Warning: Could not load static JSON at ${config.static}. Proceeding with dynamic data only.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const dynamicTruth = {};
|
|
97
|
+
if (config.dynamic) {
|
|
98
|
+
const rawResults = await resolveAll(config.dynamic, { timeout: options.timeout });
|
|
99
|
+
for (const [key, source] of Object.entries(config.dynamic)) {
|
|
100
|
+
const rawData = rawResults[key];
|
|
101
|
+
if (rawData === null && options.failLoudly) {
|
|
102
|
+
throw new Error(`[llmweb] Dynamic Truth Error: Source "${key}" failed to resolve.`);
|
|
103
|
+
}
|
|
104
|
+
if (rawData && source.map) {
|
|
105
|
+
try {
|
|
106
|
+
dynamicTruth[key] = transform(rawData, source.map);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (options.failLoudly) {
|
|
109
|
+
throw new Error(`[llmweb] Transformation Error: Failed to map source "${key}". ${error}`);
|
|
110
|
+
}
|
|
111
|
+
console.error(`[llmweb] Warning: Mapping failed for "${key}". Using raw data.`);
|
|
112
|
+
dynamicTruth[key] = rawData;
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
dynamicTruth[key] = rawData;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return merge(staticTruth, dynamicTruth);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/index.ts
|
|
123
|
+
import { readFileSync } from "fs";
|
|
124
|
+
import { join } from "path";
|
|
125
|
+
var nodeLoader = async (path) => {
|
|
126
|
+
const fullPath = path.startsWith("/") ? path : join(process.cwd(), path);
|
|
127
|
+
return readFileSync(fullPath, "utf-8");
|
|
128
|
+
};
|
|
129
|
+
async function createLLMSource(config, options = {}) {
|
|
130
|
+
return compileLLM(config, nodeLoader, options);
|
|
131
|
+
}
|
|
4
132
|
|
|
5
133
|
// src/adapters/next.tsx
|
|
6
134
|
import { jsx } from "react/jsx-runtime";
|
package/dist/adapters/react.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,14 +17,24 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/adapters/react.tsx
|
|
21
31
|
var react_exports = {};
|
|
22
32
|
__export(react_exports, {
|
|
33
|
+
LLMInjector: () => LLMInjector,
|
|
23
34
|
LLMJson: () => LLMJson
|
|
24
35
|
});
|
|
25
36
|
module.exports = __toCommonJS(react_exports);
|
|
37
|
+
var import_react = __toESM(require("react"));
|
|
26
38
|
|
|
27
39
|
// src/core/resolver.ts
|
|
28
40
|
async function resolveAll(dynamicSources, options = {}) {
|
|
@@ -103,24 +115,15 @@ function merge(staticData, dynamicResults) {
|
|
|
103
115
|
};
|
|
104
116
|
}
|
|
105
117
|
|
|
106
|
-
// src/
|
|
107
|
-
|
|
108
|
-
var import_node_path = require("path");
|
|
109
|
-
|
|
110
|
-
// src/core/injector.ts
|
|
111
|
-
function toWindowString(data, key = "__LLM__") {
|
|
112
|
-
const json = JSON.stringify(data);
|
|
113
|
-
return `window.${key} = ${json};`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// src/index.ts
|
|
117
|
-
async function createLLMSource(config, options = {}) {
|
|
118
|
+
// src/core/compiler.ts
|
|
119
|
+
async function compileLLM(config, loader, options = {}) {
|
|
118
120
|
let staticTruth = {};
|
|
119
121
|
if (config.static) {
|
|
120
122
|
try {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
const content = await loader(config.static);
|
|
124
|
+
if (content) {
|
|
125
|
+
staticTruth = JSON.parse(content);
|
|
126
|
+
}
|
|
124
127
|
} catch (error) {
|
|
125
128
|
if (options.failLoudly) {
|
|
126
129
|
throw new Error(`[llmweb] Static Truth Error: Failed to load/parse JSON at ${config.static}. ${error}`);
|
|
@@ -154,6 +157,25 @@ async function createLLMSource(config, options = {}) {
|
|
|
154
157
|
return merge(staticTruth, dynamicTruth);
|
|
155
158
|
}
|
|
156
159
|
|
|
160
|
+
// src/index.ts
|
|
161
|
+
var import_node_fs = require("fs");
|
|
162
|
+
var import_node_path = require("path");
|
|
163
|
+
|
|
164
|
+
// src/core/injector.ts
|
|
165
|
+
function toWindowString(data, key = "__LLM__") {
|
|
166
|
+
const json = JSON.stringify(data);
|
|
167
|
+
return `window.${key} = ${json};`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/index.ts
|
|
171
|
+
var nodeLoader = async (path) => {
|
|
172
|
+
const fullPath = path.startsWith("/") ? path : (0, import_node_path.join)(process.cwd(), path);
|
|
173
|
+
return (0, import_node_fs.readFileSync)(fullPath, "utf-8");
|
|
174
|
+
};
|
|
175
|
+
async function createLLMSource(config, options = {}) {
|
|
176
|
+
return compileLLM(config, nodeLoader, options);
|
|
177
|
+
}
|
|
178
|
+
|
|
157
179
|
// src/adapters/react.tsx
|
|
158
180
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
159
181
|
async function LLMJson({
|
|
@@ -185,7 +207,47 @@ async function LLMJson({
|
|
|
185
207
|
}
|
|
186
208
|
);
|
|
187
209
|
}
|
|
210
|
+
function LLMInjector({
|
|
211
|
+
config,
|
|
212
|
+
mode = "script",
|
|
213
|
+
targetKey = "__LLM__",
|
|
214
|
+
className
|
|
215
|
+
}) {
|
|
216
|
+
const [truth, setTruth] = import_react.default.useState(null);
|
|
217
|
+
import_react.default.useEffect(() => {
|
|
218
|
+
let mounted = true;
|
|
219
|
+
createLLMSource(config).then((data) => {
|
|
220
|
+
if (mounted) setTruth(data);
|
|
221
|
+
});
|
|
222
|
+
return () => {
|
|
223
|
+
mounted = false;
|
|
224
|
+
};
|
|
225
|
+
}, [config]);
|
|
226
|
+
if (!truth) return null;
|
|
227
|
+
if (mode === "window") {
|
|
228
|
+
const scriptBody = toWindowString(truth, targetKey);
|
|
229
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
230
|
+
"script",
|
|
231
|
+
{
|
|
232
|
+
id: `llm-window-${targetKey}`,
|
|
233
|
+
dangerouslySetInnerHTML: { __html: scriptBody }
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
if (mode === "pre") {
|
|
238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { id: "llm-truth-pre", className, children: JSON.stringify(truth, null, 2) });
|
|
239
|
+
}
|
|
240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
241
|
+
"script",
|
|
242
|
+
{
|
|
243
|
+
id: "llm-truth-script",
|
|
244
|
+
type: "application/llm+json",
|
|
245
|
+
dangerouslySetInnerHTML: { __html: JSON.stringify(truth) }
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
}
|
|
188
249
|
// Annotate the CommonJS export names for ESM import in node:
|
|
189
250
|
0 && (module.exports = {
|
|
251
|
+
LLMInjector,
|
|
190
252
|
LLMJson
|
|
191
253
|
});
|