@unrdf/kgc-runtime 26.4.2

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 (70) hide show
  1. package/IMPLEMENTATION_SUMMARY.json +150 -0
  2. package/PLUGIN_SYSTEM_SUMMARY.json +149 -0
  3. package/README.md +98 -0
  4. package/TRANSACTION_IMPLEMENTATION.json +119 -0
  5. package/capability-map.md +93 -0
  6. package/docs/api-stability.md +269 -0
  7. package/docs/extensions/plugin-development.md +382 -0
  8. package/package.json +40 -0
  9. package/plugins/registry.json +35 -0
  10. package/src/admission-gate.mjs +414 -0
  11. package/src/api-version.mjs +373 -0
  12. package/src/atomic-admission.mjs +310 -0
  13. package/src/bounds.mjs +289 -0
  14. package/src/bulkhead-manager.mjs +280 -0
  15. package/src/capsule.mjs +524 -0
  16. package/src/crdt.mjs +361 -0
  17. package/src/enhanced-bounds.mjs +614 -0
  18. package/src/executor.mjs +73 -0
  19. package/src/freeze-restore.mjs +521 -0
  20. package/src/index.mjs +62 -0
  21. package/src/materialized-views.mjs +371 -0
  22. package/src/merge.mjs +472 -0
  23. package/src/plugin-isolation.mjs +392 -0
  24. package/src/plugin-manager.mjs +441 -0
  25. package/src/projections-api.mjs +336 -0
  26. package/src/projections-cli.mjs +238 -0
  27. package/src/projections-docs.mjs +300 -0
  28. package/src/projections-ide.mjs +278 -0
  29. package/src/receipt.mjs +340 -0
  30. package/src/rollback.mjs +258 -0
  31. package/src/saga-orchestrator.mjs +355 -0
  32. package/src/schemas.mjs +1330 -0
  33. package/src/storage-optimization.mjs +359 -0
  34. package/src/tool-registry.mjs +272 -0
  35. package/src/transaction.mjs +466 -0
  36. package/src/validators.mjs +485 -0
  37. package/src/work-item.mjs +449 -0
  38. package/templates/plugin-template/README.md +58 -0
  39. package/templates/plugin-template/index.mjs +162 -0
  40. package/templates/plugin-template/plugin.json +19 -0
  41. package/test/admission-gate.test.mjs +583 -0
  42. package/test/api-version.test.mjs +74 -0
  43. package/test/atomic-admission.test.mjs +155 -0
  44. package/test/bounds.test.mjs +341 -0
  45. package/test/bulkhead-manager.test.mjs +236 -0
  46. package/test/capsule.test.mjs +625 -0
  47. package/test/crdt.test.mjs +215 -0
  48. package/test/enhanced-bounds.test.mjs +487 -0
  49. package/test/freeze-restore.test.mjs +472 -0
  50. package/test/materialized-views.test.mjs +243 -0
  51. package/test/merge.test.mjs +665 -0
  52. package/test/plugin-isolation.test.mjs +109 -0
  53. package/test/plugin-manager.test.mjs +208 -0
  54. package/test/projections-api.test.mjs +293 -0
  55. package/test/projections-cli.test.mjs +204 -0
  56. package/test/projections-docs.test.mjs +173 -0
  57. package/test/projections-ide.test.mjs +230 -0
  58. package/test/receipt.test.mjs +295 -0
  59. package/test/rollback.test.mjs +132 -0
  60. package/test/saga-orchestrator.test.mjs +279 -0
  61. package/test/schemas.test.mjs +716 -0
  62. package/test/storage-optimization.test.mjs +503 -0
  63. package/test/tool-registry.test.mjs +341 -0
  64. package/test/transaction.test.mjs +189 -0
  65. package/test/validators.test.mjs +463 -0
  66. package/test/work-item.test.mjs +548 -0
  67. package/test/work-item.test.mjs.bak +548 -0
  68. package/var/kgc/test-atomic-log.json +519 -0
  69. package/var/kgc/test-cascading-log.json +145 -0
  70. package/vitest.config.mjs +18 -0
@@ -0,0 +1,300 @@
1
+ /**
2
+ * @fileoverview Π_docs - Documentation Generation Projections
3
+ * Transforms KGC structures into Markdown documentation with code examples
4
+ */
5
+
6
+ import { z } from 'zod';
7
+
8
+ /**
9
+ * Documentation projection schema
10
+ */
11
+ export const DocsProjectionSchema = z.object({
12
+ type: z.literal('docs'),
13
+ format: z.enum(['markdown', 'html', 'json']),
14
+ content: z.string(),
15
+ frontMatter: z.record(z.any()).optional(),
16
+ sections: z.array(z.object({
17
+ title: z.string(),
18
+ level: z.number(),
19
+ content: z.string(),
20
+ })).optional(),
21
+ crossRefs: z.array(z.object({
22
+ source: z.string(),
23
+ target: z.string(),
24
+ type: z.string(),
25
+ })).optional(),
26
+ });
27
+
28
+ /**
29
+ * @typedef {z.infer<typeof DocsProjectionSchema>} DocsProjection
30
+ */
31
+
32
+ /**
33
+ * Escape markdown special characters
34
+ * @param {string} text - Text to escape
35
+ * @returns {string} Escaped text
36
+ */
37
+ function escapeMarkdown(text) {
38
+ return text.replace(/([*_`#\[\]()>])/g, '\\$1');
39
+ }
40
+
41
+ /**
42
+ * Generate markdown heading
43
+ * @param {string} text - Heading text
44
+ * @param {number} level - Heading level (1-6)
45
+ * @returns {string} Markdown heading
46
+ */
47
+ function heading(text, level = 1) {
48
+ return `${'#'.repeat(Math.min(level, 6))} ${text}`;
49
+ }
50
+
51
+ /**
52
+ * Generate markdown code block
53
+ * @param {string} code - Code content
54
+ * @param {string} [language='javascript'] - Language for syntax highlighting
55
+ * @returns {string} Markdown code block
56
+ */
57
+ function codeBlock(code, language = 'javascript') {
58
+ return `\`\`\`${language}\n${code}\n\`\`\``;
59
+ }
60
+
61
+ /**
62
+ * Project receipt to documentation
63
+ * @param {import('./receipt.mjs').Receipt} receipt - Receipt to document
64
+ * @returns {DocsProjection} Documentation projection
65
+ */
66
+ export function projectReceiptToDocs(receipt) {
67
+ const sections = [
68
+ {
69
+ title: 'Overview',
70
+ level: 2,
71
+ content: `Receipt ID: \`${receipt.id}\`\n\nOperation: **${receipt.operation}**\n\nTimestamp: ${receipt.timestamp}`,
72
+ },
73
+ {
74
+ title: 'Inputs',
75
+ level: 2,
76
+ content: codeBlock(JSON.stringify(receipt.inputs, null, 2), 'json'),
77
+ },
78
+ {
79
+ title: 'Outputs',
80
+ level: 2,
81
+ content: codeBlock(JSON.stringify(receipt.outputs, null, 2), 'json'),
82
+ },
83
+ {
84
+ title: 'Verification',
85
+ level: 2,
86
+ content: `Content Hash: \`${receipt.hash}\`` +
87
+ (receipt.parentHash ? `\n\nParent Hash: \`${receipt.parentHash}\`` : ''),
88
+ },
89
+ ];
90
+
91
+ const content = [
92
+ heading('Receipt Documentation', 1),
93
+ '',
94
+ ...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
95
+ ].join('\n');
96
+
97
+ return DocsProjectionSchema.parse({
98
+ type: 'docs',
99
+ format: 'markdown',
100
+ content,
101
+ frontMatter: {
102
+ id: receipt.id,
103
+ operation: receipt.operation,
104
+ timestamp: receipt.timestamp,
105
+ },
106
+ sections,
107
+ });
108
+ }
109
+
110
+ /**
111
+ * Project schema to documentation with examples
112
+ * @param {string} schemaName - Schema name
113
+ * @param {import('zod').ZodType} schema - Zod schema
114
+ * @param {Record<string, any>} [example] - Example object
115
+ * @returns {DocsProjection} Documentation projection
116
+ */
117
+ export function projectSchemaToDocs(schemaName, schema, example) {
118
+ const sections = [
119
+ {
120
+ title: 'Schema Definition',
121
+ level: 2,
122
+ content: `\`${schemaName}\` - Type-safe schema for validation and type inference.`,
123
+ },
124
+ ];
125
+
126
+ if (example) {
127
+ sections.push({
128
+ title: 'Example',
129
+ level: 2,
130
+ content: codeBlock(JSON.stringify(example, null, 2), 'json'),
131
+ });
132
+
133
+ sections.push({
134
+ title: 'Usage',
135
+ level: 2,
136
+ content: codeBlock(
137
+ `import { ${schemaName} } from '@unrdf/kgc-runtime/schemas';\n\n` +
138
+ `const validated = ${schemaName}.parse(data);`,
139
+ 'javascript'
140
+ ),
141
+ });
142
+ }
143
+
144
+ const content = [
145
+ heading(`${schemaName} Documentation`, 1),
146
+ '',
147
+ ...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
148
+ ].join('\n');
149
+
150
+ return DocsProjectionSchema.parse({
151
+ type: 'docs',
152
+ format: 'markdown',
153
+ content,
154
+ frontMatter: {
155
+ schema: schemaName,
156
+ type: 'schema-documentation',
157
+ },
158
+ sections,
159
+ });
160
+ }
161
+
162
+ /**
163
+ * Generate API documentation from function
164
+ * @param {Function} fn - Function to document
165
+ * @param {object} metadata - Function metadata
166
+ * @param {string} metadata.name - Function name
167
+ * @param {string} metadata.description - Function description
168
+ * @param {Array<{name: string, type: string, description: string}>} metadata.params - Parameters
169
+ * @param {object} metadata.returns - Return value info
170
+ * @param {string} [metadata.example] - Usage example
171
+ * @returns {DocsProjection} Documentation projection
172
+ */
173
+ export function projectFunctionToDocs(fn, metadata) {
174
+ const sections = [
175
+ {
176
+ title: 'Description',
177
+ level: 2,
178
+ content: metadata.description,
179
+ },
180
+ {
181
+ title: 'Parameters',
182
+ level: 2,
183
+ content: metadata.params.map(p =>
184
+ `- **${p.name}** (\`${p.type}\`): ${p.description}`
185
+ ).join('\n'),
186
+ },
187
+ {
188
+ title: 'Returns',
189
+ level: 2,
190
+ content: `\`${metadata.returns.type}\` - ${metadata.returns.description}`,
191
+ },
192
+ ];
193
+
194
+ if (metadata.example) {
195
+ sections.push({
196
+ title: 'Example',
197
+ level: 2,
198
+ content: codeBlock(metadata.example, 'javascript'),
199
+ });
200
+ }
201
+
202
+ const content = [
203
+ heading(`${metadata.name}()`, 1),
204
+ '',
205
+ ...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
206
+ ].join('\n');
207
+
208
+ return DocsProjectionSchema.parse({
209
+ type: 'docs',
210
+ format: 'markdown',
211
+ content,
212
+ frontMatter: {
213
+ function: metadata.name,
214
+ type: 'api-documentation',
215
+ },
216
+ sections,
217
+ });
218
+ }
219
+
220
+ /**
221
+ * Generate cross-reference links in markdown
222
+ * @param {string} text - Text with potential references
223
+ * @param {Map<string, string>} refMap - Map of reference IDs to URLs
224
+ * @returns {string} Text with markdown links
225
+ */
226
+ export function generateCrossRefs(text, refMap) {
227
+ let result = text;
228
+
229
+ for (const [ref, url] of refMap.entries()) {
230
+ const pattern = new RegExp(`\\b${ref}\\b`, 'g');
231
+ result = result.replace(pattern, `[${ref}](${url})`);
232
+ }
233
+
234
+ return result;
235
+ }
236
+
237
+ /**
238
+ * Generate table of contents from sections
239
+ * @param {Array<{title: string, level: number}>} sections - Document sections
240
+ * @returns {string} Markdown table of contents
241
+ */
242
+ export function generateTableOfContents(sections) {
243
+ const toc = sections.map(section => {
244
+ const indent = ' '.repeat(section.level - 1);
245
+ const anchor = section.title.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '');
246
+ return `${indent}- [${section.title}](#${anchor})`;
247
+ });
248
+
249
+ return '## Table of Contents\n\n' + toc.join('\n');
250
+ }
251
+
252
+ /**
253
+ * Project workflow to documentation
254
+ * @param {object} workflow - Workflow definition
255
+ * @param {string} workflow.id - Workflow ID
256
+ * @param {string} workflow.name - Workflow name
257
+ * @param {string} workflow.description - Workflow description
258
+ * @param {Array<{id: string, type: string, description: string}>} workflow.steps - Workflow steps
259
+ * @returns {DocsProjection} Documentation projection
260
+ */
261
+ export function projectWorkflowToDocs(workflow) {
262
+ const sections = [
263
+ {
264
+ title: 'Overview',
265
+ level: 2,
266
+ content: workflow.description,
267
+ },
268
+ {
269
+ title: 'Workflow Steps',
270
+ level: 2,
271
+ content: workflow.steps.map((step, i) =>
272
+ `${i + 1}. **${step.type}** (\`${step.id}\`)\n ${step.description}`
273
+ ).join('\n\n'),
274
+ },
275
+ ];
276
+
277
+ const content = [
278
+ heading(workflow.name, 1),
279
+ '',
280
+ ...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
281
+ ].join('\n');
282
+
283
+ const crossRefs = workflow.steps.map((step, i) => ({
284
+ source: workflow.id,
285
+ target: step.id,
286
+ type: 'step',
287
+ }));
288
+
289
+ return DocsProjectionSchema.parse({
290
+ type: 'docs',
291
+ format: 'markdown',
292
+ content,
293
+ frontMatter: {
294
+ workflowId: workflow.id,
295
+ name: workflow.name,
296
+ },
297
+ sections,
298
+ crossRefs,
299
+ });
300
+ }
@@ -0,0 +1,278 @@
1
+ /**
2
+ * @fileoverview Π_ide - IDE Metadata Projections
3
+ * Transforms KGC structures into LSP-compatible metadata for IDE integration
4
+ */
5
+
6
+ import { z } from 'zod';
7
+
8
+ /**
9
+ * IDE projection schema (LSP-compatible)
10
+ */
11
+ export const IDEProjectionSchema = z.object({
12
+ type: z.literal('ide'),
13
+ format: z.enum(['lsp', 'hover', 'completion', 'definition']),
14
+ content: z.record(z.any()),
15
+ uri: z.string().optional(),
16
+ range: z.object({
17
+ start: z.object({ line: z.number(), character: z.number() }),
18
+ end: z.object({ line: z.number(), character: z.number() }),
19
+ }).optional(),
20
+ });
21
+
22
+ /**
23
+ * @typedef {z.infer<typeof IDEProjectionSchema>} IDEProjection
24
+ */
25
+
26
+ /**
27
+ * LSP Position
28
+ * @typedef {{line: number, character: number}} Position
29
+ */
30
+
31
+ /**
32
+ * LSP Range
33
+ * @typedef {{start: Position, end: Position}} Range
34
+ */
35
+
36
+ /**
37
+ * Project function to LSP hover information
38
+ * @param {object} fnInfo - Function information
39
+ * @param {string} fnInfo.name - Function name
40
+ * @param {string} fnInfo.signature - Function signature
41
+ * @param {string} fnInfo.documentation - Documentation text
42
+ * @param {Array<{name: string, type: string, description: string}>} fnInfo.parameters - Parameters
43
+ * @param {object} fnInfo.returns - Return type info
44
+ * @returns {IDEProjection} IDE projection
45
+ */
46
+ export function projectFunctionToHover(fnInfo) {
47
+ const paramDocs = fnInfo.parameters.map(p =>
48
+ `@param {${p.type}} ${p.name} - ${p.description}`
49
+ ).join('\n');
50
+
51
+ const returnDoc = `@returns {${fnInfo.returns.type}} ${fnInfo.returns.description}`;
52
+
53
+ const markdown = [
54
+ `\`\`\`javascript`,
55
+ fnInfo.signature,
56
+ `\`\`\``,
57
+ '',
58
+ fnInfo.documentation,
59
+ '',
60
+ paramDocs,
61
+ returnDoc,
62
+ ].join('\n');
63
+
64
+ return IDEProjectionSchema.parse({
65
+ type: 'ide',
66
+ format: 'hover',
67
+ content: {
68
+ kind: 'markdown',
69
+ value: markdown,
70
+ },
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Project schema to LSP completion items
76
+ * @param {string} schemaName - Schema name
77
+ * @param {object} fields - Schema fields
78
+ * @returns {IDEProjection} IDE projection with completions
79
+ */
80
+ export function projectSchemaToCompletions(schemaName, fields) {
81
+ const completionItems = Object.entries(fields).map(([key, info]) => ({
82
+ label: key,
83
+ kind: 10, // LSP CompletionItemKind.Property
84
+ detail: info.type,
85
+ documentation: {
86
+ kind: 'markdown',
87
+ value: info.description || `${key} field of ${schemaName}`,
88
+ },
89
+ insertText: key,
90
+ insertTextFormat: 1, // PlainText
91
+ }));
92
+
93
+ return IDEProjectionSchema.parse({
94
+ type: 'ide',
95
+ format: 'completion',
96
+ content: {
97
+ isIncomplete: false,
98
+ items: completionItems,
99
+ },
100
+ });
101
+ }
102
+
103
+ /**
104
+ * Project function to LSP definition location
105
+ * @param {object} location - Source location
106
+ * @param {string} location.uri - File URI
107
+ * @param {Range} location.range - Location range
108
+ * @returns {IDEProjection} IDE projection
109
+ */
110
+ export function projectToDefinition(location) {
111
+ return IDEProjectionSchema.parse({
112
+ type: 'ide',
113
+ format: 'definition',
114
+ content: {
115
+ uri: location.uri,
116
+ range: location.range,
117
+ },
118
+ uri: location.uri,
119
+ range: location.range,
120
+ });
121
+ }
122
+
123
+ /**
124
+ * Project receipt to LSP diagnostic
125
+ * @param {object} issue - Issue information
126
+ * @param {string} issue.message - Error message
127
+ * @param {string} issue.severity - Severity level (error, warning, info)
128
+ * @param {Range} issue.range - Error range
129
+ * @param {string} [issue.code] - Error code
130
+ * @returns {object} LSP Diagnostic
131
+ */
132
+ export function projectToDiagnostic(issue) {
133
+ const severityMap = {
134
+ error: 1,
135
+ warning: 2,
136
+ info: 3,
137
+ hint: 4,
138
+ };
139
+
140
+ return {
141
+ range: issue.range,
142
+ severity: severityMap[issue.severity] || 1,
143
+ code: issue.code,
144
+ message: issue.message,
145
+ source: 'kgc-runtime',
146
+ };
147
+ }
148
+
149
+ /**
150
+ * Generate LSP symbol information for workspace indexing
151
+ * @param {object} symbolInfo - Symbol information
152
+ * @param {string} symbolInfo.name - Symbol name
153
+ * @param {string} symbolInfo.kind - Symbol kind (function, class, variable, etc.)
154
+ * @param {string} symbolInfo.containerName - Container name
155
+ * @param {object} symbolInfo.location - Symbol location
156
+ * @returns {object} LSP DocumentSymbol
157
+ */
158
+ export function projectToSymbol(symbolInfo) {
159
+ const kindMap = {
160
+ function: 12,
161
+ class: 5,
162
+ interface: 11,
163
+ variable: 13,
164
+ constant: 14,
165
+ property: 7,
166
+ method: 6,
167
+ };
168
+
169
+ return {
170
+ name: symbolInfo.name,
171
+ kind: kindMap[symbolInfo.kind] || 13,
172
+ location: symbolInfo.location,
173
+ containerName: symbolInfo.containerName,
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Generate code action (quick fix) for common issues
179
+ * @param {object} actionInfo - Action information
180
+ * @param {string} actionInfo.title - Action title
181
+ * @param {string} actionInfo.kind - Action kind (quickfix, refactor, etc.)
182
+ * @param {object} actionInfo.edit - Workspace edit
183
+ * @returns {object} LSP CodeAction
184
+ */
185
+ export function projectToCodeAction(actionInfo) {
186
+ return {
187
+ title: actionInfo.title,
188
+ kind: actionInfo.kind || 'quickfix',
189
+ edit: actionInfo.edit,
190
+ isPreferred: actionInfo.isPreferred || false,
191
+ };
192
+ }
193
+
194
+ /**
195
+ * Project work item to LSP code lens
196
+ * @param {object} workItem - Work item
197
+ * @param {Range} range - Code range
198
+ * @returns {object} LSP CodeLens
199
+ */
200
+ export function projectToCodeLens(workItem, range) {
201
+ return {
202
+ range,
203
+ command: {
204
+ title: `▶ ${workItem.goal}`,
205
+ command: 'kgc.executeWorkItem',
206
+ arguments: [workItem.id],
207
+ },
208
+ };
209
+ }
210
+
211
+ /**
212
+ * Generate signature help for function calls
213
+ * @param {object} fnInfo - Function information
214
+ * @param {number} activeParameter - Active parameter index
215
+ * @returns {IDEProjection} IDE projection with signature help
216
+ */
217
+ export function projectToSignatureHelp(fnInfo, activeParameter = 0) {
218
+ const parameters = fnInfo.parameters.map(p => ({
219
+ label: `${p.name}: ${p.type}`,
220
+ documentation: {
221
+ kind: 'markdown',
222
+ value: p.description,
223
+ },
224
+ }));
225
+
226
+ const signature = {
227
+ label: `${fnInfo.name}(${fnInfo.parameters.map(p => `${p.name}: ${p.type}`).join(', ')}) => ${fnInfo.returns.type}`,
228
+ documentation: {
229
+ kind: 'markdown',
230
+ value: fnInfo.documentation,
231
+ },
232
+ parameters,
233
+ };
234
+
235
+ return IDEProjectionSchema.parse({
236
+ type: 'ide',
237
+ format: 'lsp',
238
+ content: {
239
+ signatures: [signature],
240
+ activeSignature: 0,
241
+ activeParameter,
242
+ },
243
+ });
244
+ }
245
+
246
+ /**
247
+ * Generate semantic tokens for syntax highlighting
248
+ * @param {Array<{line: number, char: number, length: number, tokenType: string, modifiers?: string[]}>} tokens - Token information
249
+ * @returns {object} LSP SemanticTokens
250
+ */
251
+ export function projectToSemanticTokens(tokens) {
252
+ const tokenTypes = ['namespace', 'class', 'function', 'variable', 'property', 'parameter'];
253
+ const tokenModifiers = ['declaration', 'readonly', 'static', 'async'];
254
+
255
+ // Encode tokens as per LSP specification (delta encoding)
256
+ const data = [];
257
+ let prevLine = 0;
258
+ let prevChar = 0;
259
+
260
+ for (const token of tokens) {
261
+ const deltaLine = token.line - prevLine;
262
+ const deltaChar = deltaLine === 0 ? token.char - prevChar : token.char;
263
+ const typeIndex = tokenTypes.indexOf(token.tokenType);
264
+ const modifierBits = (token.modifiers || []).reduce(
265
+ (acc, mod) => acc | (1 << tokenModifiers.indexOf(mod)),
266
+ 0
267
+ );
268
+
269
+ data.push(deltaLine, deltaChar, token.length, typeIndex, modifierBits);
270
+
271
+ prevLine = token.line;
272
+ prevChar = token.char;
273
+ }
274
+
275
+ return {
276
+ data,
277
+ };
278
+ }