@smoothbricks/lmao 0.2.2 → 0.2.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/dist/allocator.wasm +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/JsBufferStrategy.d.ts +4 -3
- package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
- package/dist/lib/JsBufferStrategy.js +18 -11
- package/dist/lib/arrow/lease.d.ts +10 -0
- package/dist/lib/arrow/lease.d.ts.map +1 -0
- package/dist/lib/arrow/lease.js +33 -0
- package/dist/lib/arrow/utils.d.ts +3 -4
- package/dist/lib/arrow/utils.d.ts.map +1 -1
- package/dist/lib/arrow/utils.js +12 -13
- package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
- package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
- package/dist/lib/arrow/vocabularyDictionary.js +95 -0
- package/dist/lib/bufferStrategy.d.ts +3 -2
- package/dist/lib/bufferStrategy.d.ts.map +1 -1
- package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
- package/dist/lib/cloudflare/traceRows.js +3 -2
- package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/evaluatorGenerator.js +12 -11
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
- package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
- package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
- package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
- package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
- package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
- package/dist/lib/convertToArrow.d.ts +7 -2
- package/dist/lib/convertToArrow.d.ts.map +1 -1
- package/dist/lib/convertToArrow.js +499 -285
- package/dist/lib/defineOpContext.js +1 -1
- package/dist/lib/enumMetadata.d.ts +19 -0
- package/dist/lib/enumMetadata.d.ts.map +1 -0
- package/dist/lib/enumMetadata.js +86 -0
- package/dist/lib/flushScheduler.d.ts.map +1 -1
- package/dist/lib/flushScheduler.js +13 -4
- package/dist/lib/library.d.ts +16 -98
- package/dist/lib/library.d.ts.map +1 -1
- package/dist/lib/library.js +32 -525
- package/dist/lib/logBinding.d.ts +21 -27
- package/dist/lib/logBinding.d.ts.map +1 -1
- package/dist/lib/op.d.ts +30 -30
- package/dist/lib/op.d.ts.map +1 -1
- package/dist/lib/op.js +15 -22
- package/dist/lib/opContext/createOpGroup.d.ts +1 -1
- package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
- package/dist/lib/opContext/createOpGroup.js +22 -29
- package/dist/lib/opContext/defineOp.d.ts +4 -4
- package/dist/lib/opContext/defineOp.d.ts.map +1 -1
- package/dist/lib/opContext/defineOp.js +53 -10
- package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
- package/dist/lib/opContext/opTypes.d.ts +1 -1
- package/dist/lib/opContext/opTypes.d.ts.map +1 -1
- package/dist/lib/opContext/spanContextTypes.d.ts +29 -14
- package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
- package/dist/lib/opContext/types.d.ts +4 -4
- package/dist/lib/opContext/types.d.ts.map +1 -1
- package/dist/lib/physicalLayoutPlan.d.ts +89 -0
- package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
- package/dist/lib/physicalLayoutPlan.js +442 -0
- package/dist/lib/resolveMessage.d.ts +9 -0
- package/dist/lib/resolveMessage.d.ts.map +1 -0
- package/dist/lib/resolveMessage.js +63 -0
- package/dist/lib/result.d.ts +5 -7
- package/dist/lib/result.d.ts.map +1 -1
- package/dist/lib/result.js +19 -26
- package/dist/lib/runtimeHint.d.ts +35 -0
- package/dist/lib/runtimeHint.d.ts.map +1 -0
- package/dist/lib/runtimeHint.js +79 -0
- package/dist/lib/schema/types.d.ts +1 -1
- package/dist/lib/schema/types.d.ts.map +1 -1
- package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
- package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
- package/dist/lib/span-buffer/aot/v1.js +24 -0
- package/dist/lib/spanBuffer.d.ts +33 -4
- package/dist/lib/spanBuffer.d.ts.map +1 -1
- package/dist/lib/spanBuffer.js +583 -91
- package/dist/lib/spanBufferStats.d.ts +1 -1
- package/dist/lib/spanBufferStats.d.ts.map +1 -1
- package/dist/lib/spanContext.d.ts +27 -51
- package/dist/lib/spanContext.d.ts.map +1 -1
- package/dist/lib/spanContext.js +822 -344
- package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
- package/dist/lib/sqlite/sqlite-common.js +20 -21
- package/dist/lib/testing/bun-harness.d.ts +8 -3
- package/dist/lib/testing/bun-harness.d.ts.map +1 -1
- package/dist/lib/testing/bun-harness.js +30 -18
- package/dist/lib/testing/extractFacts.d.ts +1 -1
- package/dist/lib/testing/extractFacts.d.ts.map +1 -1
- package/dist/lib/testing/extractFacts.js +55 -63
- package/dist/lib/testing/facts.d.ts +1 -1
- package/dist/lib/testing/facts.d.ts.map +1 -1
- package/dist/lib/testing/queryable-span.d.ts +1 -1
- package/dist/lib/testing/queryable-span.d.ts.map +1 -1
- package/dist/lib/testing/queryable-span.js +26 -28
- package/dist/lib/testing/span-query.d.ts.map +1 -1
- package/dist/lib/testing/span-query.js +19 -22
- package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
- package/dist/lib/testing/stdio-replay.js +19 -8
- package/dist/lib/threadId.d.ts.map +1 -1
- package/dist/lib/threadId.js +6 -3
- package/dist/lib/traceRoot.d.ts +30 -8
- package/dist/lib/traceRoot.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.d.ts +17 -15
- package/dist/lib/traceRoot.es.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.js +68 -34
- package/dist/lib/traceRoot.js +11 -0
- package/dist/lib/traceRoot.node.d.ts +17 -19
- package/dist/lib/traceRoot.node.d.ts.map +1 -1
- package/dist/lib/traceRoot.node.js +66 -38
- package/dist/lib/traceTopology.d.ts +42 -0
- package/dist/lib/traceTopology.d.ts.map +1 -0
- package/dist/lib/traceTopology.js +260 -0
- package/dist/lib/tracer.d.ts +9 -5
- package/dist/lib/tracer.d.ts.map +1 -1
- package/dist/lib/tracer.js +65 -71
- package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
- package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
- package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
- package/dist/lib/tracers/StdioTracer.js +15 -13
- package/dist/lib/tracers/TestTracer.d.ts +4 -6
- package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
- package/dist/lib/tracers/TestTracer.js +6 -8
- package/dist/lib/types.d.ts +49 -32
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/vocabularyRegistry.d.ts +25 -0
- package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
- package/dist/lib/vocabularyRegistry.js +372 -0
- package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
- package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
- package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
- package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
- package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
- package/dist/lib/wasm/wasmAllocator.js +66 -44
- package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
- package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
- package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
- package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
- package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
- package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
- package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
- package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
- package/dist/lib/wasm/wasmTraceRoot.js +110 -71
- package/dist/vocabulary/register/v1.d.ts +2 -0
- package/dist/vocabulary/register/v1.d.ts.map +1 -0
- package/dist/vocabulary/register/v1.js +1 -0
- package/dist/wasm.d.ts +5 -0
- package/dist/wasm.d.ts.map +1 -0
- package/dist/wasm.js +4 -0
- package/package.json +54 -6
- package/src/index.ts +1 -0
- package/src/lib/JsBufferStrategy.ts +27 -9
- package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
- package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
- package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
- package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
- package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
- package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
- package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
- package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
- package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
- package/src/lib/__tests__/capability-span-context.test.ts +505 -0
- package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
- package/src/lib/__tests__/eager-columns.test.ts +345 -0
- package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
- package/src/lib/__tests__/enum-metadata.test.ts +177 -0
- package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
- package/src/lib/__tests__/flushScheduler.test.ts +5 -1
- package/src/lib/__tests__/identity-view.property.test.ts +179 -0
- package/src/lib/__tests__/library.test.ts +19 -235
- package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
- package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
- package/src/lib/__tests__/op-metadata.test.ts +1 -1
- package/src/lib/__tests__/op-type-safety.test.ts +5 -16
- package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
- package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
- package/src/lib/__tests__/root-context-construction.test.ts +414 -0
- package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
- package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
- package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
- package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
- package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
- package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
- package/src/lib/__tests__/test-helpers.ts +67 -12
- package/src/lib/__tests__/threadId.test.ts +62 -0
- package/src/lib/__tests__/timestamp.test.ts +221 -93
- package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
- package/src/lib/__tests__/type-narrowing.test.ts +63 -0
- package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
- package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
- package/src/lib/arrow/lease.ts +43 -0
- package/src/lib/arrow/utils.ts +10 -14
- package/src/lib/arrow/vocabularyDictionary.ts +123 -0
- package/src/lib/bufferStrategy.ts +9 -1
- package/src/lib/cloudflare/traceRows.ts +3 -2
- package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
- package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
- package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
- package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
- package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
- package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
- package/src/lib/codegen/evaluatorGenerator.ts +18 -13
- package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
- package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
- package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
- package/src/lib/convertToArrow.ts +598 -311
- package/src/lib/defineOpContext.ts +1 -1
- package/src/lib/enumMetadata.ts +121 -0
- package/src/lib/flushScheduler.ts +11 -5
- package/src/lib/library.ts +37 -595
- package/src/lib/logBinding.ts +21 -27
- package/src/lib/op.ts +75 -18
- package/src/lib/opContext/__tests__/retry.test.ts +27 -21
- package/src/lib/opContext/createOpGroup.ts +33 -31
- package/src/lib/opContext/defineOp.ts +88 -11
- package/src/lib/opContext/opGroupTypes.ts +2 -2
- package/src/lib/opContext/opTypes.ts +1 -1
- package/src/lib/opContext/spanContextTypes.ts +98 -17
- package/src/lib/opContext/types.ts +7 -3
- package/src/lib/physicalLayoutPlan.ts +598 -0
- package/src/lib/resolveMessage.ts +67 -0
- package/src/lib/result.ts +20 -33
- package/src/lib/runtimeHint.ts +98 -0
- package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
- package/src/lib/schema/builder.ts +1 -1
- package/src/lib/schema/types.ts +1 -1
- package/src/lib/span-buffer/aot/v1.ts +26 -0
- package/src/lib/spanBuffer.ts +658 -92
- package/src/lib/spanBufferStats.ts +1 -1
- package/src/lib/spanContext.ts +1350 -861
- package/src/lib/sqlite/sqlite-common.ts +20 -31
- package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
- package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
- package/src/lib/testing/bun-harness.ts +94 -43
- package/src/lib/testing/extractFacts.ts +64 -78
- package/src/lib/testing/facts.ts +1 -1
- package/src/lib/testing/queryable-span.ts +23 -30
- package/src/lib/testing/span-query.ts +16 -20
- package/src/lib/testing/stdio-replay.ts +25 -8
- package/src/lib/testing/vitest-harness.ts +1 -1
- package/src/lib/threadId.ts +6 -3
- package/src/lib/traceRoot.es.ts +77 -42
- package/src/lib/traceRoot.node.ts +75 -46
- package/src/lib/traceRoot.ts +41 -14
- package/src/lib/traceTopology.ts +279 -0
- package/src/lib/tracer.ts +109 -98
- package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
- package/src/lib/tracers/StdioTracer.ts +15 -13
- package/src/lib/tracers/TestTracer.ts +6 -8
- package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
- package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
- package/src/lib/types.ts +64 -33
- package/src/lib/vocabularyRegistry.ts +439 -0
- package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
- package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
- package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
- package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
- package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
- package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
- package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
- package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
- package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
- package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
- package/src/lib/wasm/wasmAllocator.ts +131 -96
- package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
- package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
- package/src/lib/wasm/wasmTraceRoot.ts +140 -78
- package/src/vocabulary/register/v1.ts +1 -0
- package/src/wasm.ts +19 -0
- package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
- package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
- package/src/lib/wasm/allocator.zig +0 -948
|
@@ -17,11 +17,18 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
|
+
activeMaterializerMode,
|
|
20
21
|
type ColumnEntry,
|
|
21
|
-
type ColumnWriter,
|
|
22
22
|
type ColumnWriterExtension,
|
|
23
|
-
|
|
23
|
+
generateColumnWriterClass,
|
|
24
24
|
} from '@smoothbricks/arrow-builder';
|
|
25
|
+
import {
|
|
26
|
+
type EnumLookupDescriptor,
|
|
27
|
+
resolveEnumLookupDescriptor,
|
|
28
|
+
type SchemaEnumLookupDescriptor,
|
|
29
|
+
} from '../enumMetadata.js';
|
|
30
|
+
import { decodeVocabularyMessage } from '../resolveMessage.js';
|
|
31
|
+
import type { MessageLayoutFamily, MessagePhysicalLayout } from '../runtimeHint.js';
|
|
25
32
|
import {
|
|
26
33
|
ENTRY_TYPE_DEBUG,
|
|
27
34
|
ENTRY_TYPE_ERROR,
|
|
@@ -31,10 +38,16 @@ import {
|
|
|
31
38
|
ENTRY_TYPE_TRACE,
|
|
32
39
|
ENTRY_TYPE_WARN,
|
|
33
40
|
} from '../schema/systemSchema.js';
|
|
34
|
-
import {
|
|
41
|
+
import { getSchemaType } from '../schema/typeGuards.js';
|
|
35
42
|
import type { InferSchema, LogSchema } from '../schema/types.js';
|
|
36
|
-
|
|
37
|
-
import type {
|
|
43
|
+
import type { AnySpanBuffer } from '../types.js';
|
|
44
|
+
import type { VocabularyGeneration } from '../vocabularyRegistry.js';
|
|
45
|
+
import type { WriterState } from './fixedPositionWriterGenerator.js';
|
|
46
|
+
import {
|
|
47
|
+
materializeSpanLoggerClass,
|
|
48
|
+
type SpanLoggerColumnMode,
|
|
49
|
+
type SpanLoggerPlan,
|
|
50
|
+
} from './spanLoggerClosureMaterializer.js';
|
|
38
51
|
|
|
39
52
|
// =============================================================================
|
|
40
53
|
// SINGLETON HELPERS OBJECT
|
|
@@ -47,10 +60,17 @@ import type { AnySpanBuffer, SpanBuffer } from '../types.js';
|
|
|
47
60
|
* Singleton - same object shared by all generated SpanLogger classes.
|
|
48
61
|
*/
|
|
49
62
|
export const SPAN_LOGGER_HELPERS: {
|
|
63
|
+
normalizeOperationalTemplate: (template: string) => string;
|
|
50
64
|
setNullBit: (bitmap: Uint8Array, idx: number) => void;
|
|
65
|
+
decodeVocabularyMessage: (generation: VocabularyGeneration, denseIndex: number) => string;
|
|
51
66
|
fillNullBitmapRange: (bitmap: Uint8Array, startIdx: number, endIdx: number) => void;
|
|
52
67
|
fillBooleanBitmapRange: (bitmap: Uint8Array, startIdx: number, endIdx: number, value: boolean) => void;
|
|
53
68
|
} = {
|
|
69
|
+
normalizeOperationalTemplate: (template: string) => {
|
|
70
|
+
if (template.indexOf('{{') === -1 && template.indexOf('}}') === -1) return template;
|
|
71
|
+
return template.replaceAll('{{', '{').replaceAll('}}', '}');
|
|
72
|
+
},
|
|
73
|
+
decodeVocabularyMessage,
|
|
54
74
|
setNullBit: (bitmap: Uint8Array, idx: number) => {
|
|
55
75
|
bitmap[idx >>> 3] |= 1 << (idx & 7);
|
|
56
76
|
},
|
|
@@ -156,12 +176,17 @@ export const SPAN_LOGGER_HELPERS: {
|
|
|
156
176
|
export interface BaseSpanLogger<T extends LogSchema> {
|
|
157
177
|
/** Log info-level message */
|
|
158
178
|
info(message: string): FluentLogEntry<T>;
|
|
179
|
+
info(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
159
180
|
/** Log debug-level message */
|
|
160
181
|
debug(message: string): FluentLogEntry<T>;
|
|
161
182
|
/** Log warning message */
|
|
162
183
|
warn(message: string): FluentLogEntry<T>;
|
|
184
|
+
warn(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
163
185
|
/** Log error message */
|
|
164
186
|
error(message: string): FluentLogEntry<T>;
|
|
187
|
+
error(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
188
|
+
/** Log trace-level message */
|
|
189
|
+
trace(message: string): FluentLogEntry<T>;
|
|
165
190
|
}
|
|
166
191
|
|
|
167
192
|
/**
|
|
@@ -188,9 +213,12 @@ export type FluentLogEntry<T extends LogSchema> = {
|
|
|
188
213
|
|
|
189
214
|
// Logging methods for continued chaining
|
|
190
215
|
info(message: string): FluentLogEntry<T>;
|
|
216
|
+
info(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
191
217
|
debug(message: string): FluentLogEntry<T>;
|
|
192
218
|
warn(message: string): FluentLogEntry<T>;
|
|
219
|
+
warn(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
193
220
|
error(message: string): FluentLogEntry<T>;
|
|
221
|
+
error(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
194
222
|
trace(message: string): FluentLogEntry<T>;
|
|
195
223
|
} & {
|
|
196
224
|
[K in keyof InferSchema<T>]: (value: InferSchema<T>[K]) => FluentLogEntry<T>;
|
|
@@ -207,52 +235,50 @@ export type FluentLogEntry<T extends LogSchema> = {
|
|
|
207
235
|
* This is the FULL type returned by createSpanLogger().
|
|
208
236
|
* Users see SpanLogger<T> which hides internal methods.
|
|
209
237
|
*/
|
|
210
|
-
export type SpanLoggerImpl<T extends LogSchema> =
|
|
238
|
+
export type SpanLoggerImpl<T extends LogSchema> = {
|
|
211
239
|
info(message: string): FluentLogEntry<T>;
|
|
240
|
+
info(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
212
241
|
debug(message: string): FluentLogEntry<T>;
|
|
213
242
|
warn(message: string): FluentLogEntry<T>;
|
|
243
|
+
warn(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
214
244
|
error(message: string): FluentLogEntry<T>;
|
|
245
|
+
error(template: string, fields: Partial<InferSchema<T>>): FluentLogEntry<T>;
|
|
215
246
|
trace(message: string): FluentLogEntry<T>;
|
|
247
|
+
_infoTemplate(vocabularyIndex: number): FluentLogEntry<T>;
|
|
248
|
+
_debugTemplate(vocabularyIndex: number): FluentLogEntry<T>;
|
|
249
|
+
_warnTemplate(vocabularyIndex: number): FluentLogEntry<T>;
|
|
250
|
+
_errorTemplate(vocabularyIndex: number): FluentLogEntry<T>;
|
|
251
|
+
_traceTemplate(vocabularyIndex: number): FluentLogEntry<T>;
|
|
216
252
|
readonly scope: Readonly<Record<string, unknown>>;
|
|
217
253
|
_setScope(attributes: ScopeUpdate<T>): void;
|
|
254
|
+
_prefillScopedAttributesOn(buffer: AnySpanBuffer): void;
|
|
255
|
+
} & {
|
|
256
|
+
[K in keyof InferSchema<T>]: (value: InferSchema<T>[K]) => FluentLogEntry<T>;
|
|
218
257
|
};
|
|
219
258
|
|
|
259
|
+
export type SpanLoggerConstructor<T extends LogSchema> = new (state: WriterState) => SpanLoggerImpl<T>;
|
|
260
|
+
|
|
220
261
|
export type ScopeUpdate<T extends LogSchema> = {
|
|
221
262
|
[K in keyof InferSchema<T>]?: InferSchema<T>[K] | null;
|
|
222
263
|
};
|
|
223
264
|
|
|
224
|
-
/**
|
|
225
|
-
* Generate enum value mapping code
|
|
226
|
-
* Creates a switch-case statement for compile-time enum mapping
|
|
227
|
-
*/
|
|
228
|
-
function generateEnumMapping(fieldName: string, enumValues: readonly string[]): string {
|
|
229
|
-
const cases = enumValues.map((value, index) => ` case ${JSON.stringify(value)}: return ${index};`).join('\n');
|
|
230
|
-
|
|
231
|
-
return `
|
|
232
|
-
function getEnumIndex_${fieldName}(value) {
|
|
233
|
-
switch(value) {
|
|
234
|
-
${cases}
|
|
235
|
-
default: return 0;
|
|
236
|
-
}
|
|
237
|
-
}`;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
265
|
/**
|
|
241
266
|
* Generate override fluent setters for enum fields.
|
|
242
267
|
* These convert string values to numeric indices before writing to the buffer.
|
|
243
268
|
* The buffer expects numeric indices (after the enum map removal change).
|
|
244
269
|
*/
|
|
245
|
-
function generateEnumFluentSetters(
|
|
270
|
+
function generateEnumFluentSetters(
|
|
271
|
+
enumFields: readonly EnumLookupDescriptor[],
|
|
272
|
+
enumEncoderNames: Readonly<Record<string, string>>,
|
|
273
|
+
): string {
|
|
246
274
|
const setters: string[] = [];
|
|
247
275
|
|
|
248
|
-
for (const fieldName of
|
|
276
|
+
for (const { fieldName } of enumFields) {
|
|
277
|
+
const encoderName = enumEncoderNames[fieldName];
|
|
249
278
|
setters.push(`
|
|
250
|
-
/**
|
|
251
|
-
* Override fluent setter for ${fieldName} to convert string → index.
|
|
252
|
-
* Buffer expects numeric index, not string value.
|
|
253
|
-
*/
|
|
279
|
+
/** Convert the declared enum string to its schema-order index. */
|
|
254
280
|
${fieldName}(value) {
|
|
255
|
-
const idx =
|
|
281
|
+
const idx = ${encoderName}(value);
|
|
256
282
|
this._buffer.${fieldName}(this._writeIndex, idx);
|
|
257
283
|
return this;
|
|
258
284
|
}`);
|
|
@@ -302,7 +328,7 @@ function generateSetScopeMethod(): string {
|
|
|
302
328
|
*/
|
|
303
329
|
function generatePrefillScopedAttributesMethod(
|
|
304
330
|
schemaFields: readonly ColumnEntry[],
|
|
305
|
-
|
|
331
|
+
enumEncoderNames: Readonly<Record<string, string>>,
|
|
306
332
|
): string {
|
|
307
333
|
const columnFills = schemaFields.map(([fieldName, fieldSchema]) => {
|
|
308
334
|
const columnName = fieldName;
|
|
@@ -327,8 +353,9 @@ function generatePrefillScopedAttributesMethod(
|
|
|
327
353
|
|
|
328
354
|
// Value processing based on type
|
|
329
355
|
let valueExpr = 'scopeValue';
|
|
330
|
-
|
|
331
|
-
|
|
356
|
+
const enumEncoderName = enumEncoderNames[fieldName];
|
|
357
|
+
if (lmaoType === 'enum' && enumEncoderName !== undefined) {
|
|
358
|
+
valueExpr = `${enumEncoderName}(scopeValue)`;
|
|
332
359
|
}
|
|
333
360
|
|
|
334
361
|
// For string arrays (category/text), use manual loop instead of fill()
|
|
@@ -372,30 +399,45 @@ function generatePrefillScopedAttributesMethod(
|
|
|
372
399
|
/**
|
|
373
400
|
* Build the extension for SpanLogger that extends ColumnWriter
|
|
374
401
|
*/
|
|
375
|
-
function buildSpanLoggerExtension(
|
|
402
|
+
function buildSpanLoggerExtension(
|
|
403
|
+
schema: LogSchema,
|
|
404
|
+
messageLayoutFamily: MessageLayoutFamily,
|
|
405
|
+
messagePhysicalLayout: MessagePhysicalLayout,
|
|
406
|
+
eagerColumns: readonly string[],
|
|
407
|
+
enumLookup: SchemaEnumLookupDescriptor,
|
|
408
|
+
): ColumnWriterExtension {
|
|
376
409
|
const schemaFields = schema._columns;
|
|
377
410
|
|
|
378
|
-
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const enumValues = getEnumValues(fieldSchema);
|
|
385
|
-
|
|
386
|
-
if (lmaoType === 'enum' && enumValues) {
|
|
387
|
-
enumMappings.push(generateEnumMapping(fieldName, enumValues));
|
|
388
|
-
enumFieldNames.add(fieldName);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
411
|
+
const enumEncoderNames: Record<string, string> = Object.create(null);
|
|
412
|
+
const enumEncoderBindings = enumLookup.ordered.map(({ fieldName }, index) => {
|
|
413
|
+
const encoderName = `encodeEnum${index}`;
|
|
414
|
+
enumEncoderNames[fieldName] = encoderName;
|
|
415
|
+
return ` const ${encoderName} = enumLookup.byField[${JSON.stringify(fieldName)}].encode;`;
|
|
416
|
+
});
|
|
391
417
|
|
|
392
418
|
// Generate methods
|
|
393
419
|
const setScopeMethod = generateSetScopeMethod();
|
|
394
|
-
const prefillMethod = generatePrefillScopedAttributesMethod(schemaFields,
|
|
395
|
-
const enumFluentSetters = generateEnumFluentSetters(
|
|
420
|
+
const prefillMethod = generatePrefillScopedAttributesMethod(schemaFields, enumEncoderNames);
|
|
421
|
+
const enumFluentSetters = generateEnumFluentSetters(enumLookup.ordered, enumEncoderNames);
|
|
422
|
+
const staticMessageWrite = (entryType: number): string => {
|
|
423
|
+
switch (messagePhysicalLayout) {
|
|
424
|
+
case 'current':
|
|
425
|
+
return `const localMessageId = this._state._physicalLayoutPlan.encodeLocalMessage(vocabularyIndex);
|
|
426
|
+
if (localMessageId === 0) {
|
|
427
|
+
this._buffer.message_values[idx] = helpers.decodeVocabularyMessage(this._buffer._vocabularyGeneration, vocabularyIndex);
|
|
428
|
+
} else {
|
|
429
|
+
this._buffer._messageIds[idx] = localMessageId;
|
|
430
|
+
}`;
|
|
431
|
+
case 'specialized':
|
|
432
|
+
return 'this._buffer._logHeaders[idx] = vocabularyIndex + 1;';
|
|
433
|
+
case 'packed':
|
|
434
|
+
return `if (vocabularyIndex > 0x00fffffe) throw new RangeError('Packed message dense index exceeds 0xFFFFFE');
|
|
435
|
+
this._buffer._rowHeaders[idx] = ((((vocabularyIndex + 1) << 8) | ${entryType}) >>> 0);`;
|
|
436
|
+
}
|
|
437
|
+
};
|
|
396
438
|
|
|
397
439
|
return {
|
|
398
|
-
|
|
440
|
+
preallocatedColumns: eagerColumns,
|
|
399
441
|
|
|
400
442
|
// Entry type constants (inlined from lmao.ts)
|
|
401
443
|
classPreamble: `
|
|
@@ -406,109 +448,88 @@ function buildSpanLoggerExtension(schema: LogSchema): ColumnWriterExtension {
|
|
|
406
448
|
const ENTRY_TYPE_TRACE = ${ENTRY_TYPE_TRACE};
|
|
407
449
|
const ENTRY_TYPE_FF_ACCESS = ${ENTRY_TYPE_FF_ACCESS};
|
|
408
450
|
const ENTRY_TYPE_FF_USAGE = ${ENTRY_TYPE_FF_USAGE};
|
|
409
|
-
|
|
410
|
-
${enumMappings.join('\n')}
|
|
411
|
-
`,
|
|
412
|
-
|
|
413
|
-
// SpanLogger starts at writeIndex 1, so first nextRow() makes it 2
|
|
414
|
-
// (Rows 0 and 1 are reserved for span-start and span-end)
|
|
415
|
-
// Sync buffer's writeIndex - needed for Arrow conversion
|
|
416
|
-
constructorCode: `
|
|
417
|
-
this._writeIndex = 1;
|
|
418
|
-
this._buffer._writeIndex = 2;
|
|
451
|
+
${enumEncoderBindings.join('\n')}
|
|
419
452
|
`,
|
|
420
453
|
|
|
421
|
-
// Check for overflow before writing, switch to overflow buffer if needed.
|
|
422
|
-
// Overflow when _writeIndex >= capacity (buffer is full, no room for this write).
|
|
423
|
-
// Buffer.getOrCreateOverflow() handles: stats notification, capacity tuning, buffer creation.
|
|
424
|
-
// We just need to switch this._buffer and prefill scope on the new buffer.
|
|
425
454
|
methods:
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
455
|
+
// The optional fields argument is the untransformed fallback. JavaScript evaluates
|
|
456
|
+
// the receiver, template, and object initializers before this method runs. Lowered
|
|
457
|
+
// calls use _infoTemplate/_warnTemplate/_errorTemplate plus direct setters instead.
|
|
458
|
+
// Context-owned append advances the shared active buffer and returns the literal row.
|
|
459
|
+
`info(message, fields) {
|
|
460
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_INFO);
|
|
461
|
+
${messageLayoutFamily === 'static-only' ? `throw new TypeError('Dynamic log write reached a static-only callsite plan');` : 'this._buffer.message_values[idx] = helpers.normalizeOperationalTemplate(message);'}
|
|
462
|
+
if (fields !== undefined) {
|
|
463
|
+
this.with(fields);
|
|
430
464
|
}
|
|
465
|
+
return this;
|
|
431
466
|
}
|
|
432
467
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
// We sync this._writeIndex so fluent setters write at correct row.
|
|
437
|
-
`info(message) {
|
|
438
|
-
this._checkOverflow();
|
|
439
|
-
const idx = this._buffer._traceRoot.writeLogEntry(this._buffer, ENTRY_TYPE_INFO);
|
|
440
|
-
this._writeIndex = idx;
|
|
441
|
-
if (this._buffer.message_values) {
|
|
442
|
-
this._buffer.message_values[idx] = message;
|
|
443
|
-
if (this._buffer.message_nulls) {
|
|
444
|
-
helpers.setNullBit(this._buffer.message_nulls, idx);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
this._buffer.constructor.stats.totalWrites++;
|
|
468
|
+
_infoTemplate(vocabularyIndex) {
|
|
469
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_INFO);
|
|
470
|
+
${messageLayoutFamily === 'dynamic-only' ? `throw new TypeError('Static log write reached a dynamic-only callsite plan');` : staticMessageWrite(ENTRY_TYPE_INFO)}
|
|
448
471
|
return this;
|
|
449
472
|
}
|
|
450
473
|
|
|
451
474
|
` +
|
|
452
475
|
// Write a debug log entry.
|
|
453
476
|
`debug(message) {
|
|
454
|
-
this.
|
|
455
|
-
|
|
456
|
-
this
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
this._buffer.constructor.stats.totalWrites++;
|
|
477
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_DEBUG);
|
|
478
|
+
${messageLayoutFamily === 'static-only' ? `throw new TypeError('Dynamic log write reached a static-only callsite plan');` : 'this._buffer.message_values[idx] = message;'}
|
|
479
|
+
return this;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
_debugTemplate(vocabularyIndex) {
|
|
483
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_DEBUG);
|
|
484
|
+
${messageLayoutFamily === 'dynamic-only' ? `throw new TypeError('Static log write reached a dynamic-only callsite plan');` : staticMessageWrite(ENTRY_TYPE_DEBUG)}
|
|
464
485
|
return this;
|
|
465
486
|
}
|
|
466
487
|
|
|
467
488
|
` +
|
|
468
489
|
// Write a warn log entry.
|
|
469
|
-
`warn(message) {
|
|
470
|
-
this.
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
this._buffer.message_values[idx] = message;
|
|
475
|
-
if (this._buffer.message_nulls) {
|
|
476
|
-
helpers.setNullBit(this._buffer.message_nulls, idx);
|
|
477
|
-
}
|
|
490
|
+
`warn(message, fields) {
|
|
491
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_WARN);
|
|
492
|
+
${messageLayoutFamily === 'static-only' ? `throw new TypeError('Dynamic log write reached a static-only callsite plan');` : 'this._buffer.message_values[idx] = helpers.normalizeOperationalTemplate(message);'}
|
|
493
|
+
if (fields !== undefined) {
|
|
494
|
+
this.with(fields);
|
|
478
495
|
}
|
|
479
|
-
this
|
|
496
|
+
return this;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
_warnTemplate(vocabularyIndex) {
|
|
500
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_WARN);
|
|
501
|
+
${messageLayoutFamily === 'dynamic-only' ? `throw new TypeError('Static log write reached a dynamic-only callsite plan');` : staticMessageWrite(ENTRY_TYPE_WARN)}
|
|
480
502
|
return this;
|
|
481
503
|
}
|
|
482
504
|
|
|
483
505
|
` +
|
|
484
506
|
// Write an error log entry.
|
|
485
|
-
`error(message) {
|
|
486
|
-
this.
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
this._buffer.message_values[idx] = message;
|
|
491
|
-
if (this._buffer.message_nulls) {
|
|
492
|
-
helpers.setNullBit(this._buffer.message_nulls, idx);
|
|
493
|
-
}
|
|
507
|
+
`error(message, fields) {
|
|
508
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_ERROR);
|
|
509
|
+
${messageLayoutFamily === 'static-only' ? `throw new TypeError('Dynamic log write reached a static-only callsite plan');` : 'this._buffer.message_values[idx] = helpers.normalizeOperationalTemplate(message);'}
|
|
510
|
+
if (fields !== undefined) {
|
|
511
|
+
this.with(fields);
|
|
494
512
|
}
|
|
495
|
-
this
|
|
513
|
+
return this;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
_errorTemplate(vocabularyIndex) {
|
|
517
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_ERROR);
|
|
518
|
+
${messageLayoutFamily === 'dynamic-only' ? `throw new TypeError('Static log write reached a dynamic-only callsite plan');` : staticMessageWrite(ENTRY_TYPE_ERROR)}
|
|
496
519
|
return this;
|
|
497
520
|
}
|
|
498
521
|
|
|
499
522
|
` +
|
|
500
523
|
// Write a trace log entry.
|
|
501
524
|
`trace(message) {
|
|
502
|
-
this.
|
|
503
|
-
|
|
504
|
-
this
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
this._buffer.constructor.stats.totalWrites++;
|
|
525
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_TRACE);
|
|
526
|
+
${messageLayoutFamily === 'static-only' ? `throw new TypeError('Dynamic log write reached a static-only callsite plan');` : 'this._buffer.message_values[idx] = message;'}
|
|
527
|
+
return this;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
_traceTemplate(vocabularyIndex) {
|
|
531
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_TRACE);
|
|
532
|
+
${messageLayoutFamily === 'dynamic-only' ? `throw new TypeError('Static log write reached a dynamic-only callsite plan');` : staticMessageWrite(ENTRY_TYPE_TRACE)}
|
|
512
533
|
return this;
|
|
513
534
|
}
|
|
514
535
|
|
|
@@ -532,15 +553,8 @@ function buildSpanLoggerExtension(schema: LogSchema): ColumnWriterExtension {
|
|
|
532
553
|
// Write a feature flag access entry (internal method, not on public type).
|
|
533
554
|
// Called by FeatureFlagEvaluator to log flag access.
|
|
534
555
|
`ffAccess(flagName, value) {
|
|
535
|
-
this.
|
|
536
|
-
|
|
537
|
-
this._writeIndex = idx;
|
|
538
|
-
if (this._buffer.message_values) {
|
|
539
|
-
this._buffer.message_values[idx] = flagName;
|
|
540
|
-
if (this._buffer.message_nulls) {
|
|
541
|
-
helpers.setNullBit(this._buffer.message_nulls, idx);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
556
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_FF_ACCESS);
|
|
557
|
+
${messageLayoutFamily === 'static-only' ? `throw new TypeError('Feature flag write reached a static-only callsite plan');` : 'this._buffer.message_values[idx] = flagName;'}
|
|
544
558
|
if (this._buffer.ff_value_values) {
|
|
545
559
|
const strValue = value === null || value === undefined ? 'null' : String(value);
|
|
546
560
|
this._buffer.ff_value_values[idx] = strValue;
|
|
@@ -548,23 +562,14 @@ function buildSpanLoggerExtension(schema: LogSchema): ColumnWriterExtension {
|
|
|
548
562
|
helpers.setNullBit(this._buffer.ff_value_nulls, idx);
|
|
549
563
|
}
|
|
550
564
|
}
|
|
551
|
-
this._buffer.constructor.stats.totalWrites++;
|
|
552
565
|
}
|
|
553
566
|
|
|
554
567
|
` +
|
|
555
568
|
// Write a feature flag usage entry (internal method, not on public type).
|
|
556
569
|
// Called by FeatureFlagEvaluator to log flag usage.
|
|
557
570
|
`ffUsage(flagName, context) {
|
|
558
|
-
this.
|
|
559
|
-
|
|
560
|
-
this._writeIndex = idx;
|
|
561
|
-
if (this._buffer.message_values) {
|
|
562
|
-
this._buffer.message_values[idx] = flagName;
|
|
563
|
-
if (this._buffer.message_nulls) {
|
|
564
|
-
helpers.setNullBit(this._buffer.message_nulls, idx);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
this._buffer.constructor.stats.totalWrites++;
|
|
571
|
+
const idx = this._state._appendWriterEntry(ENTRY_TYPE_FF_USAGE);
|
|
572
|
+
${messageLayoutFamily === 'static-only' ? `throw new TypeError('Feature flag write reached a static-only callsite plan');` : 'this._buffer.message_values[idx] = flagName;'}
|
|
568
573
|
if (context) {
|
|
569
574
|
this.with(context);
|
|
570
575
|
}
|
|
@@ -648,6 +653,7 @@ function buildSpanLoggerExtension(schema: LogSchema): ColumnWriterExtension {
|
|
|
648
653
|
// Use singleton helpers object (created once at module load)
|
|
649
654
|
dependencies: {
|
|
650
655
|
helpers: SPAN_LOGGER_HELPERS,
|
|
656
|
+
enumLookup,
|
|
651
657
|
},
|
|
652
658
|
};
|
|
653
659
|
}
|
|
@@ -655,48 +661,112 @@ function buildSpanLoggerExtension(schema: LogSchema): ColumnWriterExtension {
|
|
|
655
661
|
/**
|
|
656
662
|
* Cache for generated SpanLogger classes per schema.
|
|
657
663
|
*/
|
|
658
|
-
const spanLoggerClassCache = new WeakMap<LogSchema, unknown
|
|
664
|
+
const spanLoggerClassCache = new WeakMap<LogSchema, Map<string, unknown>>();
|
|
659
665
|
|
|
660
|
-
function isSpanLoggerConstructor<T extends LogSchema>(
|
|
661
|
-
value: unknown,
|
|
662
|
-
): value is new (
|
|
663
|
-
buffer: AnySpanBuffer,
|
|
664
|
-
) => SpanLoggerImpl<T> {
|
|
666
|
+
function isSpanLoggerConstructor<T extends LogSchema>(value: unknown): value is SpanLoggerConstructor<T> {
|
|
665
667
|
return typeof value === 'function';
|
|
666
668
|
}
|
|
667
669
|
|
|
670
|
+
function generateStateBoundSpanLoggerClass(schema: LogSchema, extension: ColumnWriterExtension): string {
|
|
671
|
+
const source = generateColumnWriterClass(schema, 'GeneratedSpanLogger', extension);
|
|
672
|
+
const constructorStart = source.indexOf(' constructor(buffer) {');
|
|
673
|
+
const firstSetter = schema._columnNames[0];
|
|
674
|
+
const methodsStart = source.indexOf(
|
|
675
|
+
firstSetter === undefined ? '\n info(message, fields) {' : `\n ${firstSetter}(value) {`,
|
|
676
|
+
constructorStart,
|
|
677
|
+
);
|
|
678
|
+
if (constructorStart < 0 || methodsStart < 0) {
|
|
679
|
+
throw new Error('Failed to locate generated SpanLogger class boundaries');
|
|
680
|
+
}
|
|
681
|
+
const stateConstructor = ' constructor(state) {\n this._state = state;\n }\n';
|
|
682
|
+
return (source.slice(0, constructorStart) + stateConstructor + source.slice(methodsStart + 1))
|
|
683
|
+
.replaceAll('this._buffer', 'this._state._buffer')
|
|
684
|
+
.replaceAll('this._writeIndex', '(this._state._buffer._writeIndex - 1)');
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/** Compiled materializer: render class source and evaluate it with `new Function`. */
|
|
688
|
+
function compileSpanLoggerClass(
|
|
689
|
+
schema: LogSchema,
|
|
690
|
+
messageLayoutFamily: MessageLayoutFamily,
|
|
691
|
+
messagePhysicalLayout: MessagePhysicalLayout,
|
|
692
|
+
eagerColumns: readonly string[],
|
|
693
|
+
enumLookup: SchemaEnumLookupDescriptor,
|
|
694
|
+
): unknown {
|
|
695
|
+
const extension = buildSpanLoggerExtension(
|
|
696
|
+
schema,
|
|
697
|
+
messageLayoutFamily,
|
|
698
|
+
messagePhysicalLayout,
|
|
699
|
+
eagerColumns,
|
|
700
|
+
enumLookup,
|
|
701
|
+
);
|
|
702
|
+
const classCode = generateStateBoundSpanLoggerClass(schema, extension).trim();
|
|
703
|
+
return new Function('helpers', 'enumLookup', classCode)(SPAN_LOGGER_HELPERS, enumLookup);
|
|
704
|
+
}
|
|
705
|
+
|
|
668
706
|
/**
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
707
|
+
* Schema/config -> pure-data plan consumed by the closure-composed (no-eval)
|
|
708
|
+
* materializer. Mirrors the inputs the compiled renderer bakes into source:
|
|
709
|
+
* per-column access mode (arrow-builder's buildColumnAccessorPlan semantics),
|
|
710
|
+
* layout family/physical layout, and the injected singleton dependencies.
|
|
711
|
+
*/
|
|
712
|
+
function buildSpanLoggerPlan(
|
|
713
|
+
schema: LogSchema,
|
|
714
|
+
messageLayoutFamily: MessageLayoutFamily,
|
|
715
|
+
messagePhysicalLayout: MessagePhysicalLayout,
|
|
716
|
+
eagerColumns: readonly string[],
|
|
717
|
+
enumLookup: SchemaEnumLookupDescriptor,
|
|
718
|
+
): SpanLoggerPlan {
|
|
719
|
+
const preallocated = new Set(eagerColumns);
|
|
720
|
+
const columns = schema._columns.map(([fieldName, fieldSchema]) => {
|
|
721
|
+
const isEager =
|
|
722
|
+
typeof fieldSchema === 'object' && fieldSchema !== null && Reflect.get(fieldSchema, '__eager') === true;
|
|
723
|
+
const mode: SpanLoggerColumnMode = isEager ? 'eager' : preallocated.has(fieldName) ? 'preallocated' : 'lazy';
|
|
724
|
+
return { name: fieldName, schemaType: getSchemaType(fieldSchema), mode };
|
|
725
|
+
});
|
|
726
|
+
return {
|
|
727
|
+
columns,
|
|
728
|
+
messageLayoutFamily,
|
|
729
|
+
messagePhysicalLayout,
|
|
730
|
+
helpers: SPAN_LOGGER_HELPERS,
|
|
731
|
+
enumLookup,
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Create the state-only SpanLogger constructor selected for one schema/layout family.
|
|
676
737
|
*
|
|
677
|
-
*
|
|
738
|
+
* Selects the materializer via activeMaterializerMode(): the compiled renderer
|
|
739
|
+
* (string codegen) where `new Function` is allowed, the closure-composed
|
|
740
|
+
* materializer where it is forbidden (e.g. workerd). Cache keys are
|
|
741
|
+
* mode-prefixed so a forced override never returns the other mode's class.
|
|
678
742
|
*/
|
|
679
743
|
export function createSpanLoggerClass<T extends LogSchema>(
|
|
680
744
|
schema: T,
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
745
|
+
messageLayoutFamily: MessageLayoutFamily = 'mixed',
|
|
746
|
+
messagePhysicalLayout: MessagePhysicalLayout = 'current',
|
|
747
|
+
eagerColumns: readonly string[] = [],
|
|
748
|
+
enumLookup: SchemaEnumLookupDescriptor = resolveEnumLookupDescriptor(schema),
|
|
749
|
+
): SpanLoggerConstructor<T> {
|
|
750
|
+
const mode = activeMaterializerMode();
|
|
751
|
+
const cacheKey = `${mode}:${messageLayoutFamily}:${messagePhysicalLayout}:${eagerColumns.join('\u0000')}`;
|
|
752
|
+
let familyClasses = spanLoggerClassCache.get(schema);
|
|
753
|
+
let SpanLoggerClass = familyClasses?.get(cacheKey);
|
|
686
754
|
|
|
687
755
|
if (!SpanLoggerClass) {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
756
|
+
SpanLoggerClass =
|
|
757
|
+
mode === 'compiled'
|
|
758
|
+
? compileSpanLoggerClass(schema, messageLayoutFamily, messagePhysicalLayout, eagerColumns, enumLookup)
|
|
759
|
+
: materializeSpanLoggerClass(
|
|
760
|
+
buildSpanLoggerPlan(schema, messageLayoutFamily, messagePhysicalLayout, eagerColumns, enumLookup),
|
|
761
|
+
);
|
|
694
762
|
|
|
695
763
|
if (!isSpanLoggerConstructor<LogSchema>(SpanLoggerClass)) {
|
|
696
764
|
throw new Error('Failed to generate SpanLogger constructor');
|
|
697
765
|
}
|
|
698
766
|
|
|
699
|
-
|
|
767
|
+
familyClasses ??= new Map();
|
|
768
|
+
familyClasses.set(cacheKey, SpanLoggerClass);
|
|
769
|
+
spanLoggerClassCache.set(schema, familyClasses);
|
|
700
770
|
}
|
|
701
771
|
|
|
702
772
|
if (!isSpanLoggerConstructor<T>(SpanLoggerClass)) {
|
|
@@ -706,14 +776,8 @@ export function createSpanLoggerClass<T extends LogSchema>(
|
|
|
706
776
|
return SpanLoggerClass;
|
|
707
777
|
}
|
|
708
778
|
|
|
709
|
-
/**
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
* @param schema - Tag attribute schema
|
|
713
|
-
* @param buffer - SpanBuffer to write to
|
|
714
|
-
*/
|
|
715
|
-
export function createSpanLogger<T extends LogSchema>(schema: T, buffer: SpanBuffer<T>): SpanLoggerImpl<T> {
|
|
716
|
-
const SpanLoggerClass = createSpanLoggerClass(schema);
|
|
717
|
-
return new SpanLoggerClass(buffer);
|
|
779
|
+
/** Create a SpanLogger bound to an existing SpanContext writer state. */
|
|
780
|
+
export function createSpanLogger<T extends LogSchema>(schema: T, state: WriterState): SpanLoggerImpl<T> {
|
|
781
|
+
return new (createSpanLoggerClass(schema))(state);
|
|
718
782
|
}
|
|
719
783
|
//#endregion smoo/lmao!n/codegen-spanlogger
|