@unrdf/hooks 5.0.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.
Files changed (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/package.json +70 -0
  4. package/src/hooks/builtin-hooks.mjs +296 -0
  5. package/src/hooks/condition-cache.mjs +109 -0
  6. package/src/hooks/condition-evaluator.mjs +722 -0
  7. package/src/hooks/define-hook.mjs +211 -0
  8. package/src/hooks/effect-sandbox-worker.mjs +170 -0
  9. package/src/hooks/effect-sandbox.mjs +517 -0
  10. package/src/hooks/file-resolver.mjs +387 -0
  11. package/src/hooks/hook-chain-compiler.mjs +236 -0
  12. package/src/hooks/hook-executor-batching.mjs +277 -0
  13. package/src/hooks/hook-executor.mjs +465 -0
  14. package/src/hooks/hook-management.mjs +202 -0
  15. package/src/hooks/hook-scheduler.mjs +413 -0
  16. package/src/hooks/knowledge-hook-engine.mjs +358 -0
  17. package/src/hooks/knowledge-hook-manager.mjs +269 -0
  18. package/src/hooks/observability.mjs +531 -0
  19. package/src/hooks/policy-pack.mjs +572 -0
  20. package/src/hooks/quad-pool.mjs +249 -0
  21. package/src/hooks/quality-metrics.mjs +544 -0
  22. package/src/hooks/security/error-sanitizer.mjs +257 -0
  23. package/src/hooks/security/path-validator.mjs +194 -0
  24. package/src/hooks/security/sandbox-restrictions.mjs +331 -0
  25. package/src/hooks/telemetry.mjs +167 -0
  26. package/src/index.mjs +101 -0
  27. package/src/security/sandbox/browser-executor.mjs +220 -0
  28. package/src/security/sandbox/detector.mjs +342 -0
  29. package/src/security/sandbox/isolated-vm-executor.mjs +373 -0
  30. package/src/security/sandbox/vm2-executor.mjs +217 -0
  31. package/src/security/sandbox/worker-executor-runtime.mjs +74 -0
  32. package/src/security/sandbox/worker-executor.mjs +212 -0
  33. package/src/security/sandbox-adapter.mjs +141 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * @file Quad Object Pool for UNRDF Knowledge Hooks.
3
+ * @module hooks/quad-pool
4
+ *
5
+ * @description
6
+ * Pre-allocated object pool for quad transformations to eliminate
7
+ * allocation overhead (20μs → ~0μs per transform).
8
+ *
9
+ * WARNING: Pooled quads are MUTABLE. Use with care:
10
+ * - Only use for transient operations within hooks
11
+ * - Do NOT store pooled quads in stores (they will be reused)
12
+ * - Call release() when done with a quad
13
+ * - Use clone() if you need to persist a quad
14
+ */
15
+
16
+ /**
17
+ * @typedef {Object} PooledQuad
18
+ * @property {import('rdf-js').Term} subject - Subject term
19
+ * @property {import('rdf-js').Term} predicate - Predicate term
20
+ * @property {import('rdf-js').Term} object - Object term
21
+ * @property {import('rdf-js').Term} graph - Graph term
22
+ * @property {boolean} _pooled - Internal marker for pooled objects
23
+ */
24
+
25
+ /**
26
+ * Object pool for RDF quads.
27
+ *
28
+ * @class QuadPool
29
+ */
30
+ export class QuadPool {
31
+ /**
32
+ * Create a new quad pool.
33
+ *
34
+ * @param {object} options - Pool options
35
+ * @param {number} options.size - Initial pool size (default: 1000)
36
+ * @param {boolean} options.autoGrow - Auto-grow pool when exhausted (default: true)
37
+ */
38
+ constructor(options = {}) {
39
+ /** @type {number} */
40
+ this.size = options.size || 1000;
41
+
42
+ /** @type {boolean} */
43
+ this.autoGrow = options.autoGrow !== false;
44
+
45
+ /** @type {Array<PooledQuad>} */
46
+ this.pool = new Array(this.size);
47
+
48
+ /** @type {number} */
49
+ this.index = 0;
50
+
51
+ /** @type {number} */
52
+ this.acquired = 0;
53
+
54
+ /** @type {number} */
55
+ this.highWaterMark = 0;
56
+
57
+ // Initialize pool with empty quad objects
58
+ for (let i = 0; i < this.size; i++) {
59
+ this.pool[i] = this._createEmptyQuad();
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Create an empty quad object for the pool.
65
+ *
66
+ * @private
67
+ * @returns {PooledQuad} - Empty quad object
68
+ */
69
+ _createEmptyQuad() {
70
+ return {
71
+ subject: null,
72
+ predicate: null,
73
+ object: null,
74
+ graph: null,
75
+ _pooled: true,
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Acquire a quad from the pool.
81
+ *
82
+ * @param {import('rdf-js').Term} subject - Subject term
83
+ * @param {import('rdf-js').Term} predicate - Predicate term
84
+ * @param {import('rdf-js').Term} object - Object term
85
+ * @param {import('rdf-js').Term} [graph] - Graph term (optional)
86
+ * @returns {PooledQuad} - Pooled quad with assigned values
87
+ *
88
+ * @example
89
+ * const quad = quadPool.acquire(subject, predicate, object, graph);
90
+ * // Use quad...
91
+ * quadPool.release(quad);
92
+ */
93
+ acquire(subject, predicate, object, graph = null) {
94
+ const quad = this.pool[this.index];
95
+
96
+ // Update quad values
97
+ quad.subject = subject;
98
+ quad.predicate = predicate;
99
+ quad.object = object;
100
+ quad.graph = graph;
101
+
102
+ // Move to next slot (circular)
103
+ this.index = (this.index + 1) % this.size;
104
+ this.acquired++;
105
+
106
+ // Track high water mark
107
+ if (this.acquired > this.highWaterMark) {
108
+ this.highWaterMark = this.acquired;
109
+ }
110
+
111
+ // Auto-grow if needed
112
+ if (this.autoGrow && this.acquired >= this.size) {
113
+ this._grow();
114
+ }
115
+
116
+ return quad;
117
+ }
118
+
119
+ /**
120
+ * Release a quad back to the pool.
121
+ *
122
+ * @param {PooledQuad} quad - Quad to release
123
+ */
124
+ release(quad) {
125
+ if (quad && quad._pooled) {
126
+ // Clear references for GC
127
+ quad.subject = null;
128
+ quad.predicate = null;
129
+ quad.object = null;
130
+ quad.graph = null;
131
+ this.acquired = Math.max(0, this.acquired - 1);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Clone a pooled quad to a non-pooled object.
137
+ * Use this when you need to persist a quad beyond the current operation.
138
+ *
139
+ * @param {PooledQuad} quad - Quad to clone
140
+ * @param {Function} dataFactory - Data factory with quad() method
141
+ * @returns {import('rdf-js').Quad} - Non-pooled quad
142
+ */
143
+ clone(quad, dataFactory) {
144
+ return dataFactory.quad(quad.subject, quad.predicate, quad.object, quad.graph);
145
+ }
146
+
147
+ /**
148
+ * Grow the pool by doubling its size.
149
+ *
150
+ * @private
151
+ */
152
+ _grow() {
153
+ const newSize = this.size * 2;
154
+ const newPool = new Array(newSize);
155
+
156
+ // Copy existing quads
157
+ for (let i = 0; i < this.size; i++) {
158
+ newPool[i] = this.pool[i];
159
+ }
160
+
161
+ // Add new empty quads
162
+ for (let i = this.size; i < newSize; i++) {
163
+ newPool[i] = this._createEmptyQuad();
164
+ }
165
+
166
+ this.pool = newPool;
167
+ this.size = newSize;
168
+ }
169
+
170
+ /**
171
+ * Reset the pool (clear all references, reset index).
172
+ */
173
+ reset() {
174
+ for (let i = 0; i < this.size; i++) {
175
+ const quad = this.pool[i];
176
+ quad.subject = null;
177
+ quad.predicate = null;
178
+ quad.object = null;
179
+ quad.graph = null;
180
+ }
181
+ this.index = 0;
182
+ this.acquired = 0;
183
+ }
184
+
185
+ /**
186
+ * Get pool statistics.
187
+ *
188
+ * @returns {{size: number, acquired: number, available: number, highWaterMark: number}} - Pool stats
189
+ */
190
+ stats() {
191
+ return {
192
+ size: this.size,
193
+ acquired: this.acquired,
194
+ available: this.size - this.acquired,
195
+ highWaterMark: this.highWaterMark,
196
+ utilizationPercent: ((this.acquired / this.size) * 100).toFixed(1),
197
+ };
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Shared global quad pool instance.
203
+ * @type {QuadPool}
204
+ */
205
+ export const quadPool = new QuadPool({ size: 1000 });
206
+
207
+ /**
208
+ * Create a pooled transformation function.
209
+ *
210
+ * Wraps a transformation function to use pooled quads for intermediate
211
+ * results, improving performance for chained transformations.
212
+ *
213
+ * @param {Function} transformFn - Original transformation function
214
+ * @param {QuadPool} [pool] - Pool to use (default: global quadPool)
215
+ * @returns {Function} - Pooled transformation function
216
+ *
217
+ * @example
218
+ * const pooledTrim = createPooledTransform(trimLiterals);
219
+ * const result = pooledTrim(quad);
220
+ */
221
+ export function createPooledTransform(transformFn, pool = quadPool) {
222
+ return function pooledTransform(quad) {
223
+ const result = transformFn(quad);
224
+
225
+ // If result is different from input, use pool
226
+ if (result !== quad) {
227
+ return pool.acquire(result.subject, result.predicate, result.object, result.graph);
228
+ }
229
+
230
+ return quad;
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Check if a quad is from the pool.
236
+ *
237
+ * @param {object} quad - Quad to check
238
+ * @returns {boolean} - True if quad is pooled
239
+ */
240
+ export function isPooledQuad(quad) {
241
+ return quad && quad._pooled === true;
242
+ }
243
+
244
+ export default {
245
+ QuadPool,
246
+ quadPool,
247
+ createPooledTransform,
248
+ isPooledQuad,
249
+ };