@kaleabdenbel/llmweb 1.0.4 → 1.0.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.
package/dist/index.mjs ADDED
@@ -0,0 +1,163 @@
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
+ const { static: staticRef, dynamic, ...topLevelMetadata } = config;
83
+ let staticTruth = { ...topLevelMetadata };
84
+ if (staticRef) {
85
+ try {
86
+ if (typeof staticRef === "object") {
87
+ staticTruth = { ...staticTruth, ...staticRef };
88
+ } else {
89
+ const content = await loader(staticRef);
90
+ if (content) {
91
+ staticTruth = { ...staticTruth, ...JSON.parse(content) };
92
+ }
93
+ }
94
+ } catch (error) {
95
+ if (options.failLoudly) {
96
+ throw new Error(`[llmweb] Static Truth Error: Failed to load/parse JSON at ${staticRef}. ${error}`);
97
+ }
98
+ console.warn(`[llmweb] Warning: Could not load static JSON at ${staticRef}. Proceeding with dynamic data only.`);
99
+ }
100
+ }
101
+ const dynamicTruth = {};
102
+ if (config.dynamic) {
103
+ const rawResults = await resolveAll(config.dynamic, { timeout: options.timeout });
104
+ for (const [key, source] of Object.entries(config.dynamic)) {
105
+ const rawData = rawResults[key];
106
+ if (rawData === null && options.failLoudly) {
107
+ throw new Error(`[llmweb] Dynamic Truth Error: Source "${key}" failed to resolve.`);
108
+ }
109
+ if (rawData && source.map) {
110
+ try {
111
+ dynamicTruth[key] = transform(rawData, source.map);
112
+ } catch (error) {
113
+ if (options.failLoudly) {
114
+ throw new Error(`[llmweb] Transformation Error: Failed to map source "${key}". ${error}`);
115
+ }
116
+ console.error(`[llmweb] Warning: Mapping failed for "${key}". Using raw data.`);
117
+ dynamicTruth[key] = rawData;
118
+ }
119
+ } else {
120
+ dynamicTruth[key] = rawData;
121
+ }
122
+ }
123
+ }
124
+ return merge(staticTruth, dynamicTruth);
125
+ }
126
+
127
+ // src/core/injector.ts
128
+ function toScriptString(data) {
129
+ const json = JSON.stringify(data);
130
+ return `<script type="application/llm+json">${json}</script>`;
131
+ }
132
+ function toWindowString(data, key = "__LLM__") {
133
+ const json = JSON.stringify(data);
134
+ return `window.${key} = ${json};`;
135
+ }
136
+
137
+ // src/index.ts
138
+ async function createLLMSource(config, options = {}) {
139
+ const nodeLoader = async (path) => {
140
+ try {
141
+ const fs = await import(
142
+ /* webpackIgnore: true */
143
+ "fs"
144
+ );
145
+ const nodePath = await import(
146
+ /* webpackIgnore: true */
147
+ "path"
148
+ );
149
+ const fullPath = path.startsWith("/") ? path : nodePath.join(process.cwd(), path);
150
+ return fs.readFileSync(fullPath, "utf-8");
151
+ } catch (error) {
152
+ console.warn(`[llmweb] Warning: 'node:fs' not available. Skipping static file load: ${path}`);
153
+ return null;
154
+ }
155
+ };
156
+ return compileLLM(config, nodeLoader, options);
157
+ }
158
+ export {
159
+ createLLMSource,
160
+ toScriptString,
161
+ toWindowString,
162
+ transform
163
+ };
@@ -0,0 +1,22 @@
1
+ import { M as MapSchema } from './index-B8G8cw7b.mjs';
2
+
3
+ /**
4
+ * Transforms source data according to a MapSchema.
5
+ * The schema keys represent the target structure, and the values
6
+ * represent the source keys or transformation functions.
7
+ */
8
+ declare function transform(sourceData: any, schema: MapSchema): any;
9
+
10
+ /**
11
+ * Logic to generate injection strings for DOM discovery.
12
+ */
13
+ /**
14
+ * Wraps JSON data in a <script type="application/llm+json"> tag.
15
+ */
16
+ declare function toScriptString(data: any): string;
17
+ /**
18
+ * Creates a global assignment string (e.g., window.__LLM__ = ...).
19
+ */
20
+ declare function toWindowString(data: any, key?: string): string;
21
+
22
+ export { toWindowString as a, transform as b, toScriptString as t };
@@ -0,0 +1,22 @@
1
+ import { M as MapSchema } from './index-B8G8cw7b.js';
2
+
3
+ /**
4
+ * Transforms source data according to a MapSchema.
5
+ * The schema keys represent the target structure, and the values
6
+ * represent the source keys or transformation functions.
7
+ */
8
+ declare function transform(sourceData: any, schema: MapSchema): any;
9
+
10
+ /**
11
+ * Logic to generate injection strings for DOM discovery.
12
+ */
13
+ /**
14
+ * Wraps JSON data in a <script type="application/llm+json"> tag.
15
+ */
16
+ declare function toScriptString(data: any): string;
17
+ /**
18
+ * Creates a global assignment string (e.g., window.__LLM__ = ...).
19
+ */
20
+ declare function toWindowString(data: any, key?: string): string;
21
+
22
+ export { toWindowString as a, transform as b, toScriptString as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaleabdenbel/llmweb",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A compiler for LLM-readable truth from static and dynamic sources.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -48,8 +48,8 @@
48
48
  "scripts": {
49
49
  "build": "npm run build:lib && npm run build:cli",
50
50
  "build:lib": "tsup src/index.ts src/index.browser.ts src/adapters/next.tsx src/adapters/react.tsx src/adapters/vanilla.ts src/adapters/express.ts --format cjs,esm --dts --clean --no-splitting",
51
- "build:cli": "tsup src/cli.ts --format cjs --no-dts --clean --no-splitting",
52
- "dev": "npm run build:lib && npm run build:cli",
51
+ "build:cli": "tsup src/cli.ts --format cjs --no-dts --no-splitting",
52
+ "dev": "npm run build",
53
53
  "lint": "tsc",
54
54
  "test": "vitest run"
55
55
  },