@spooky-sync/core 0.0.1-canary.15 → 0.0.1-canary.16

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.js CHANGED
@@ -2,11 +2,6 @@ import { DateTime, Duration, RecordId, Surreal, Uuid, applyDiagnostics, createRe
2
2
  import { QueryBuilder, RecordId as RecordId$1 } from "@spooky-sync/query-builder";
3
3
  import { createWasmWorkerEngines } from "@surrealdb/wasm";
4
4
  import pino from "pino";
5
- import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
6
- import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto";
7
- import { resourceFromAttributes } from "@opentelemetry/resources";
8
- import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
9
- import { createContextKey } from "@opentelemetry/api";
10
5
  import init, { SpookyProcessor } from "@spooky-sync/ssp-wasm";
11
6
 
12
7
  //#region src/utils/surql.ts
@@ -1115,7 +1110,6 @@ var RemoteDatabaseService = class extends AbstractDatabaseService {
1115
1110
 
1116
1111
  //#endregion
1117
1112
  //#region src/services/logger/index.ts
1118
- createContextKey("Category");
1119
1113
  function mapLevelToSeverityNumber(level) {
1120
1114
  switch (level) {
1121
1115
  case "trace": return 1;
@@ -1127,6 +1121,23 @@ function mapLevelToSeverityNumber(level) {
1127
1121
  default: return 9;
1128
1122
  }
1129
1123
  }
1124
+ async function loadOtelModules(otelEndpoint) {
1125
+ const [{ LoggerProvider, BatchLogRecordProcessor }, { OTLPLogExporter }, { resourceFromAttributes }, { ATTR_SERVICE_NAME }] = await Promise.all([
1126
+ import("@opentelemetry/sdk-logs"),
1127
+ import("@opentelemetry/exporter-logs-otlp-proto"),
1128
+ import("@opentelemetry/resources"),
1129
+ import("@opentelemetry/semantic-conventions")
1130
+ ]);
1131
+ const loggerProvider = new LoggerProvider({
1132
+ resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: "spooky-client" }),
1133
+ processors: [new BatchLogRecordProcessor(new OTLPLogExporter({ url: otelEndpoint }))]
1134
+ });
1135
+ const otelLoggerCache = {};
1136
+ return (category) => {
1137
+ if (!otelLoggerCache[category]) otelLoggerCache[category] = loggerProvider.getLogger(category);
1138
+ return otelLoggerCache[category];
1139
+ };
1140
+ }
1130
1141
  function createLogger(level = "info", otelEndpoint) {
1131
1142
  const browserConfig = {
1132
1143
  asObject: true,
@@ -1135,47 +1146,43 @@ function createLogger(level = "info", otelEndpoint) {
1135
1146
  }
1136
1147
  };
1137
1148
  if (otelEndpoint) {
1138
- const loggerProvider = new LoggerProvider({
1139
- resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: "spooky-client" }),
1140
- processors: [new BatchLogRecordProcessor(new OTLPLogExporter({ url: otelEndpoint }))]
1141
- });
1142
- const otelLogger = {};
1143
- const getOtelLogger = (category) => {
1144
- if (!otelLogger[category]) otelLogger[category] = loggerProvider.getLogger(category);
1145
- return otelLogger[category];
1146
- };
1149
+ const otelReady = loadOtelModules(otelEndpoint);
1147
1150
  browserConfig.transmit = {
1148
1151
  level,
1149
1152
  send: (levelLabel, logEvent) => {
1150
- try {
1151
- const messages = [...logEvent.messages];
1152
- const severityNumber = mapLevelToSeverityNumber(levelLabel);
1153
- let body = "";
1154
- const msg = messages.pop();
1155
- if (typeof msg === "string") body = msg;
1156
- else if (msg) body = JSON.stringify(msg);
1157
- let category = "spooky-client::unknown";
1158
- const attributes = {};
1159
- for (const msg of messages) if (typeof msg === "object") {
1160
- if (msg.Category) {
1161
- category = msg.Category;
1162
- delete msg.Category;
1153
+ otelReady.then((getOtelLogger) => {
1154
+ try {
1155
+ const messages = [...logEvent.messages];
1156
+ const severityNumber = mapLevelToSeverityNumber(levelLabel);
1157
+ let body = "";
1158
+ const msg = messages.pop();
1159
+ if (typeof msg === "string") body = msg;
1160
+ else if (msg) body = JSON.stringify(msg);
1161
+ let category = "spooky-client::unknown";
1162
+ const attributes = {};
1163
+ for (const msg of messages) if (typeof msg === "object") {
1164
+ if (msg.Category) {
1165
+ category = msg.Category;
1166
+ delete msg.Category;
1167
+ }
1168
+ Object.assign(attributes, msg);
1163
1169
  }
1164
- Object.assign(attributes, msg);
1170
+ getOtelLogger(category).emit({
1171
+ severityNumber,
1172
+ severityText: levelLabel.toUpperCase(),
1173
+ body,
1174
+ attributes: {
1175
+ ...logEvent.bindings[0],
1176
+ ...attributes
1177
+ },
1178
+ timestamp: new Date(logEvent.ts)
1179
+ });
1180
+ } catch (e) {
1181
+ console.warn("Failed to transmit log to OTEL endpoint", e);
1165
1182
  }
1166
- getOtelLogger(category).emit({
1167
- severityNumber,
1168
- severityText: levelLabel.toUpperCase(),
1169
- body,
1170
- attributes: {
1171
- ...logEvent.bindings[0],
1172
- ...attributes
1173
- },
1174
- timestamp: new Date(logEvent.ts)
1175
- });
1176
- } catch (e) {
1177
- console.warn("Failed to transmit log to OTEL endpoint", e);
1178
- }
1183
+ }).catch((e) => {
1184
+ console.warn("Failed to load OpenTelemetry modules", e);
1185
+ });
1179
1186
  }
1180
1187
  };
1181
1188
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spooky-sync/core",
3
- "version": "0.0.1-canary.15",
3
+ "version": "0.0.1-canary.16",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -24,12 +24,31 @@
24
24
  "publishConfig": {
25
25
  "access": "public"
26
26
  },
27
- "dependencies": {
27
+ "peerDependencies": {
28
28
  "@opentelemetry/api": "^1.9.0",
29
29
  "@opentelemetry/exporter-logs-otlp-proto": "^0.211.0",
30
30
  "@opentelemetry/resources": "^2.6.0",
31
31
  "@opentelemetry/sdk-logs": "^0.211.0",
32
- "@opentelemetry/semantic-conventions": "^1.39.0",
32
+ "@opentelemetry/semantic-conventions": "^1.39.0"
33
+ },
34
+ "peerDependenciesMeta": {
35
+ "@opentelemetry/api": {
36
+ "optional": true
37
+ },
38
+ "@opentelemetry/exporter-logs-otlp-proto": {
39
+ "optional": true
40
+ },
41
+ "@opentelemetry/resources": {
42
+ "optional": true
43
+ },
44
+ "@opentelemetry/sdk-logs": {
45
+ "optional": true
46
+ },
47
+ "@opentelemetry/semantic-conventions": {
48
+ "optional": true
49
+ }
50
+ },
51
+ "dependencies": {
33
52
  "@spooky-sync/query-builder": "workspace:*",
34
53
  "@spooky-sync/ssp-wasm": "workspace:*",
35
54
  "@surrealdb/wasm": "^3.0.0",
@@ -1,11 +1,4 @@
1
1
  import pino, { Level, type Logger as PinoLogger, type LoggerOptions } from 'pino';
2
- import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
3
- import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-proto';
4
- import { resourceFromAttributes } from '@opentelemetry/resources';
5
- import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
6
- import { createContextKey } from '@opentelemetry/api';
7
-
8
- const CATEGORY_KEY = createContextKey('Category');
9
2
 
10
3
  export type Logger = PinoLogger;
11
4
 
@@ -30,6 +23,38 @@ function mapLevelToSeverityNumber(level: string): number {
30
23
  }
31
24
  }
32
25
 
26
+ async function loadOtelModules(otelEndpoint: string) {
27
+ const [{ LoggerProvider, BatchLogRecordProcessor }, { OTLPLogExporter }, { resourceFromAttributes }, { ATTR_SERVICE_NAME }] =
28
+ await Promise.all([
29
+ import('@opentelemetry/sdk-logs'),
30
+ import('@opentelemetry/exporter-logs-otlp-proto'),
31
+ import('@opentelemetry/resources'),
32
+ import('@opentelemetry/semantic-conventions'),
33
+ ]);
34
+
35
+ const resource = resourceFromAttributes({
36
+ [ATTR_SERVICE_NAME]: 'spooky-client',
37
+ });
38
+
39
+ const exporter = new OTLPLogExporter({
40
+ url: otelEndpoint,
41
+ });
42
+
43
+ const loggerProvider = new LoggerProvider({
44
+ resource,
45
+ processors: [new BatchLogRecordProcessor(exporter)],
46
+ });
47
+
48
+ const otelLoggerCache: Record<string, ReturnType<typeof loggerProvider.getLogger>> = {};
49
+
50
+ return (category: string) => {
51
+ if (!otelLoggerCache[category]) {
52
+ otelLoggerCache[category] = loggerProvider.getLogger(category);
53
+ }
54
+ return otelLoggerCache[category];
55
+ };
56
+ }
57
+
33
58
  export function createLogger(level: Level = 'info', otelEndpoint?: string): Logger {
34
59
  const browserConfig: LoggerOptions['browser'] = {
35
60
  asObject: true,
@@ -39,74 +64,57 @@ export function createLogger(level: Level = 'info', otelEndpoint?: string): Logg
39
64
  };
40
65
 
41
66
  if (otelEndpoint) {
42
- // Initialize OTEL LoggerProvider
43
- const resource = resourceFromAttributes({
44
- [ATTR_SERVICE_NAME]: 'spooky-client',
45
- });
46
-
47
- const exporter = new OTLPLogExporter({
48
- url: otelEndpoint,
49
- });
50
-
51
- // Pass processors in constructor as this SDK version requires it
52
- const loggerProvider = new LoggerProvider({
53
- resource,
54
- processors: [new BatchLogRecordProcessor(exporter)],
55
- });
56
-
57
- const otelLogger: Record<string, ReturnType<typeof loggerProvider.getLogger>> = {};
58
-
59
- const getOtelLogger = (category: string) => {
60
- if (!otelLogger[category]) {
61
- otelLogger[category] = loggerProvider.getLogger(category);
62
- }
63
- return otelLogger[category];
64
- };
67
+ // Start loading OTel modules eagerly (don't await — we're synchronous)
68
+ const otelReady = loadOtelModules(otelEndpoint);
65
69
 
66
70
  browserConfig.transmit = {
67
71
  level: level,
68
72
  send: (levelLabel: string, logEvent: any) => {
69
- try {
70
- const messages = [...logEvent.messages];
71
- const severityNumber = mapLevelToSeverityNumber(levelLabel);
72
-
73
- // Construct the message body
74
- let body = '';
75
- const msg = messages.pop();
76
-
77
- if (typeof msg === 'string') {
78
- body = msg;
79
- } else if (msg) {
80
- body = JSON.stringify(msg);
81
- }
73
+ otelReady.then((getOtelLogger) => {
74
+ try {
75
+ const messages = [...logEvent.messages];
76
+ const severityNumber = mapLevelToSeverityNumber(levelLabel);
77
+
78
+ // Construct the message body
79
+ let body = '';
80
+ const msg = messages.pop();
81
+
82
+ if (typeof msg === 'string') {
83
+ body = msg;
84
+ } else if (msg) {
85
+ body = JSON.stringify(msg);
86
+ }
82
87
 
83
- let category = 'spooky-client::unknown';
88
+ let category = 'spooky-client::unknown';
84
89
 
85
- const attributes = {};
86
- for (const msg of messages) {
87
- if (typeof msg === 'object') {
88
- if (msg.Category) {
89
- category = msg.Category;
90
- delete msg.Category;
90
+ const attributes = {};
91
+ for (const msg of messages) {
92
+ if (typeof msg === 'object') {
93
+ if (msg.Category) {
94
+ category = msg.Category;
95
+ delete msg.Category;
96
+ }
97
+ Object.assign(attributes, msg);
91
98
  }
92
- Object.assign(attributes, msg);
93
99
  }
94
- }
95
100
 
96
- // Emit to OTEL SDK
97
- getOtelLogger(category).emit({
98
- severityNumber: severityNumber,
99
- severityText: levelLabel.toUpperCase(),
100
- body: body,
101
- attributes: {
102
- ...logEvent.bindings[0],
103
- ...attributes,
104
- },
105
- timestamp: new Date(logEvent.ts),
106
- });
107
- } catch (e) {
108
- console.warn('Failed to transmit log to OTEL endpoint', e);
109
- }
101
+ // Emit to OTEL SDK
102
+ getOtelLogger(category).emit({
103
+ severityNumber: severityNumber,
104
+ severityText: levelLabel.toUpperCase(),
105
+ body: body,
106
+ attributes: {
107
+ ...logEvent.bindings[0],
108
+ ...attributes,
109
+ },
110
+ timestamp: new Date(logEvent.ts),
111
+ });
112
+ } catch (e) {
113
+ console.warn('Failed to transmit log to OTEL endpoint', e);
114
+ }
115
+ }).catch((e) => {
116
+ console.warn('Failed to load OpenTelemetry modules', e);
117
+ });
110
118
  },
111
119
  };
112
120
  }