@logtape/windows-eventlog 1.4.0-dev.426 → 1.4.0-dev.435

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","names":["record: LogRecord","context: string[]"],"sources":["../src/formatter.ts"],"sourcesContent":["import type { LogRecord } from \"@logtape/logtape\";\n\n/**\n * Formats a log record message into a string suitable for Windows Event Log.\n * Combines the template and arguments into a readable message.\n */\nfunction formatMessage(record: LogRecord): string {\n let message = \"\";\n\n // Combine template parts with arguments\n for (let i = 0; i < record.message.length; i++) {\n if (i % 2 === 0) {\n // Template part\n message += record.message[i];\n } else {\n // Argument - serialize it\n const arg = record.message[i];\n if (typeof arg === \"string\") {\n message += arg;\n } else {\n message += JSON.stringify(arg);\n }\n }\n }\n\n return message;\n}\n\n/**\n * Formats additional context information for the log entry.\n * Includes category, properties, and other metadata.\n */\nfunction formatContext(record: LogRecord): string {\n const context: string[] = [];\n\n // Add category if present\n if (record.category && record.category.length > 0) {\n context.push(`Category: ${record.category.join(\".\")}`);\n }\n\n // Add properties if present\n if (record.properties && Object.keys(record.properties).length > 0) {\n context.push(`Properties: ${JSON.stringify(record.properties)}`);\n }\n\n // Add timestamp\n context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);\n\n return context.length > 0 ? `\\n\\n${context.join(\"\\n\")}` : \"\";\n}\n\n/**\n * Default way of rendering a record into text that goes in the event log.\n */\nexport function defaultWindowsEventlogFormatter(record: LogRecord): string {\n const msg = formatMessage(record);\n const ctx = formatContext(record);\n return msg + ctx;\n}\n"],"mappings":";;;;;AAMA,SAAS,cAAcA,QAA2B;CAChD,IAAI,UAAU;AAGd,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,QAAQ,IACzC,KAAI,IAAI,MAAM,EAEZ,YAAW,OAAO,QAAQ;MACrB;EAEL,MAAM,MAAM,OAAO,QAAQ;AAC3B,aAAW,QAAQ,SACjB,YAAW;MAEX,YAAW,KAAK,UAAU,IAAI;CAEjC;AAGH,QAAO;AACR;;;;;AAMD,SAAS,cAAcA,QAA2B;CAChD,MAAMC,UAAoB,CAAE;AAG5B,KAAI,OAAO,YAAY,OAAO,SAAS,SAAS,EAC9C,SAAQ,MAAM,YAAY,OAAO,SAAS,KAAK,IAAI,CAAC,EAAE;AAIxD,KAAI,OAAO,cAAc,OAAO,KAAK,OAAO,WAAW,CAAC,SAAS,EAC/D,SAAQ,MAAM,cAAc,KAAK,UAAU,OAAO,WAAW,CAAC,EAAE;AAIlE,SAAQ,MAAM,aAAa,IAAI,KAAK,OAAO,WAAW,aAAa,CAAC,EAAE;AAEtE,QAAO,QAAQ,SAAS,KAAK,MAAM,QAAQ,KAAK,KAAK,CAAC,IAAI;AAC3D;;;;AAKD,SAAgB,gCAAgCD,QAA2B;CACzE,MAAM,MAAM,cAAc,OAAO;CACjC,MAAM,MAAM,cAAc,OAAO;AACjC,QAAO,MAAM;AACd"}
package/dist/sink.bun.cjs CHANGED
@@ -1,36 +1,8 @@
1
- const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
- const require_types = require('./types.cjs');
3
- const require_platform = require('./platform.cjs');
4
1
  const require_ffi_bun = require('./ffi.bun.cjs');
5
- const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
2
+ const require_sink = require('./sink.cjs');
6
3
 
7
4
  //#region src/sink.bun.ts
8
5
  /**
9
- * Formats a log record message into a string suitable for Windows Event Log.
10
- * Combines the template and arguments into a readable message.
11
- */
12
- function formatMessage(record) {
13
- let message = "";
14
- for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
15
- else {
16
- const arg = record.message[i];
17
- if (typeof arg === "string") message += arg;
18
- else message += JSON.stringify(arg);
19
- }
20
- return message;
21
- }
22
- /**
23
- * Formats additional context information for the log entry.
24
- * Includes category, properties, and other metadata.
25
- */
26
- function formatContext(record) {
27
- const context = [];
28
- if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
29
- if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
30
- context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
31
- return context.length > 0 ? `\n\n${context.join("\n")}` : "";
32
- }
33
- /**
34
6
  * Creates a Windows Event Log sink for Bun environments using FFI.
35
7
  *
36
8
  * This implementation uses Bun's native Foreign Function Interface to directly
@@ -54,47 +26,8 @@ function formatContext(record) {
54
26
  * @since 1.0.0
55
27
  */
56
28
  function getWindowsEventLogSink(options) {
57
- require_platform.validateWindowsPlatform();
58
- const { sourceName, eventIdMapping = {} } = options;
59
- const eventIds = {
60
- ...require_types.DEFAULT_EVENT_ID_MAPPING,
61
- ...eventIdMapping
62
- };
63
- let ffi = null;
64
- const metaLogger = (0, __logtape_logtape.getLogger)([
65
- "logtape",
66
- "meta",
67
- "windows-eventlog"
68
- ]);
69
- const sink = (record) => {
70
- if (!ffi) {
71
- ffi = new require_ffi_bun.WindowsEventLogFFI(sourceName);
72
- try {
73
- ffi.initialize();
74
- } catch (error) {
75
- metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
76
- ffi = null;
77
- return;
78
- }
79
- }
80
- const message = formatMessage(record);
81
- const context = formatContext(record);
82
- const fullMessage = message + context;
83
- const eventType = require_types.mapLogLevelToEventType(record.level);
84
- const eventId = eventIds[record.level];
85
- if (ffi) try {
86
- ffi.writeEvent(eventType, eventId, fullMessage);
87
- } catch (error) {
88
- metaLogger.error("Failed to write to Windows Event Log: {error}", { error });
89
- }
90
- };
91
- sink[Symbol.dispose] = () => {
92
- if (ffi) {
93
- ffi.dispose();
94
- ffi = null;
95
- }
96
- };
97
- return sink;
29
+ const ffi = new require_ffi_bun.WindowsEventLogBunFFI();
30
+ return require_sink.getWindowsEventLogSinkForFFI(ffi, options);
98
31
  }
99
32
 
100
33
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"sink.bun.d.cts","names":[],"sources":["../src/sink.bun.ts"],"sourcesContent":[],"mappings":";;;;;;;AA+EA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
1
+ {"version":3,"file":"sink.bun.d.cts","names":[],"sources":["../src/sink.bun.ts"],"sourcesContent":[],"mappings":";;;;;;;AA4BA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"sink.bun.d.ts","names":[],"sources":["../src/sink.bun.ts"],"sourcesContent":[],"mappings":";;;;;;;AA+EA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
1
+ {"version":3,"file":"sink.bun.d.ts","names":[],"sources":["../src/sink.bun.ts"],"sourcesContent":[],"mappings":";;;;;;;AA4BA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
package/dist/sink.bun.js CHANGED
@@ -1,35 +1,8 @@
1
- import { DEFAULT_EVENT_ID_MAPPING, mapLogLevelToEventType } from "./types.js";
2
- import { validateWindowsPlatform } from "./platform.js";
3
- import { WindowsEventLogFFI } from "./ffi.bun.js";
4
- import { getLogger } from "@logtape/logtape";
1
+ import { WindowsEventLogBunFFI } from "./ffi.bun.js";
2
+ import { getWindowsEventLogSinkForFFI } from "./sink.js";
5
3
 
6
4
  //#region src/sink.bun.ts
7
5
  /**
8
- * Formats a log record message into a string suitable for Windows Event Log.
9
- * Combines the template and arguments into a readable message.
10
- */
11
- function formatMessage(record) {
12
- let message = "";
13
- for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
14
- else {
15
- const arg = record.message[i];
16
- if (typeof arg === "string") message += arg;
17
- else message += JSON.stringify(arg);
18
- }
19
- return message;
20
- }
21
- /**
22
- * Formats additional context information for the log entry.
23
- * Includes category, properties, and other metadata.
24
- */
25
- function formatContext(record) {
26
- const context = [];
27
- if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
28
- if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
29
- context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
30
- return context.length > 0 ? `\n\n${context.join("\n")}` : "";
31
- }
32
- /**
33
6
  * Creates a Windows Event Log sink for Bun environments using FFI.
34
7
  *
35
8
  * This implementation uses Bun's native Foreign Function Interface to directly
@@ -53,47 +26,8 @@ function formatContext(record) {
53
26
  * @since 1.0.0
54
27
  */
55
28
  function getWindowsEventLogSink(options) {
56
- validateWindowsPlatform();
57
- const { sourceName, eventIdMapping = {} } = options;
58
- const eventIds = {
59
- ...DEFAULT_EVENT_ID_MAPPING,
60
- ...eventIdMapping
61
- };
62
- let ffi = null;
63
- const metaLogger = getLogger([
64
- "logtape",
65
- "meta",
66
- "windows-eventlog"
67
- ]);
68
- const sink = (record) => {
69
- if (!ffi) {
70
- ffi = new WindowsEventLogFFI(sourceName);
71
- try {
72
- ffi.initialize();
73
- } catch (error) {
74
- metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
75
- ffi = null;
76
- return;
77
- }
78
- }
79
- const message = formatMessage(record);
80
- const context = formatContext(record);
81
- const fullMessage = message + context;
82
- const eventType = mapLogLevelToEventType(record.level);
83
- const eventId = eventIds[record.level];
84
- if (ffi) try {
85
- ffi.writeEvent(eventType, eventId, fullMessage);
86
- } catch (error) {
87
- metaLogger.error("Failed to write to Windows Event Log: {error}", { error });
88
- }
89
- };
90
- sink[Symbol.dispose] = () => {
91
- if (ffi) {
92
- ffi.dispose();
93
- ffi = null;
94
- }
95
- };
96
- return sink;
29
+ const ffi = new WindowsEventLogBunFFI();
30
+ return getWindowsEventLogSinkForFFI(ffi, options);
97
31
  }
98
32
 
99
33
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"sink.bun.js","names":["record: LogRecord","context: string[]","options: WindowsEventLogSinkOptions","ffi: WindowsEventLogFFI | null","sink: Sink & Disposable"],"sources":["../src/sink.bun.ts"],"sourcesContent":["import type { LogRecord, Sink } from \"@logtape/logtape\";\nimport { getLogger } from \"@logtape/logtape\";\nimport type { WindowsEventLogSinkOptions } from \"./types.ts\";\nimport { DEFAULT_EVENT_ID_MAPPING, mapLogLevelToEventType } from \"./types.ts\";\nimport { validateWindowsPlatform } from \"./platform.ts\";\nimport { WindowsEventLogFFI } from \"./ffi.bun.ts\";\n\n/**\n * Formats a log record message into a string suitable for Windows Event Log.\n * Combines the template and arguments into a readable message.\n */\nfunction formatMessage(record: LogRecord): string {\n let message = \"\";\n\n // Combine template parts with arguments\n for (let i = 0; i < record.message.length; i++) {\n if (i % 2 === 0) {\n // Template part\n message += record.message[i];\n } else {\n // Argument - serialize it\n const arg = record.message[i];\n if (typeof arg === \"string\") {\n message += arg;\n } else {\n message += JSON.stringify(arg);\n }\n }\n }\n\n return message;\n}\n\n/**\n * Formats additional context information for the log entry.\n * Includes category, properties, and other metadata.\n */\nfunction formatContext(record: LogRecord): string {\n const context: string[] = [];\n\n // Add category if present\n if (record.category && record.category.length > 0) {\n context.push(`Category: ${record.category.join(\".\")}`);\n }\n\n // Add properties if present\n if (record.properties && Object.keys(record.properties).length > 0) {\n context.push(`Properties: ${JSON.stringify(record.properties)}`);\n }\n\n // Add timestamp\n context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);\n\n return context.length > 0 ? `\\n\\n${context.join(\"\\n\")}` : \"\";\n}\n\n/**\n * Creates a Windows Event Log sink for Bun environments using FFI.\n *\n * This implementation uses Bun's native Foreign Function Interface to directly\n * call Windows Event Log APIs, providing high performance logging optimized\n * for the Bun runtime.\n *\n * @param options Configuration options for the sink\n * @returns A LogTape sink that writes to Windows Event Log\n * @throws {WindowsPlatformError} If not running on Windows\n * @throws {WindowsEventLogError} If Event Log operations fail\n *\n * @example\n * ```typescript\n * import { getWindowsEventLogSink } from \"@logtape/windows-eventlog\";\n *\n * const sink = getWindowsEventLogSink({\n * sourceName: \"MyApp\"\n * });\n * ```\n *\n * @since 1.0.0\n */\nexport function getWindowsEventLogSink(\n options: WindowsEventLogSinkOptions,\n): Sink & Disposable {\n // Validate platform early\n validateWindowsPlatform();\n\n const {\n sourceName,\n eventIdMapping = {},\n } = options;\n\n // Merge with default event ID mapping\n const eventIds = { ...DEFAULT_EVENT_ID_MAPPING, ...eventIdMapping };\n\n let ffi: WindowsEventLogFFI | null = null;\n const metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n const sink: Sink & Disposable = (record: LogRecord) => {\n if (!ffi) {\n ffi = new WindowsEventLogFFI(sourceName);\n try {\n ffi.initialize();\n } catch (error) {\n metaLogger.error(\n \"Failed to initialize Windows Event Log FFI: {error}\",\n { error },\n );\n ffi = null; // Reset FFI on error\n return;\n }\n }\n\n // Format the complete message\n const message = formatMessage(record);\n const context = formatContext(record);\n const fullMessage = message + context;\n\n // Get event type and ID for this log level\n const eventType = mapLogLevelToEventType(record.level);\n const eventId = eventIds[record.level];\n\n // Write to Event Log using FFI (synchronously since Bun FFI initializes synchronously)\n if (ffi) {\n try {\n ffi.writeEvent(eventType, eventId, fullMessage);\n } catch (error) {\n metaLogger.error(\n \"Failed to write to Windows Event Log: {error}\",\n { error },\n );\n }\n }\n };\n\n // Implement Disposable for cleanup\n sink[Symbol.dispose] = () => {\n if (ffi) {\n ffi.dispose();\n ffi = null;\n }\n };\n\n return sink;\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAS,cAAcA,QAA2B;CAChD,IAAI,UAAU;AAGd,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,QAAQ,IACzC,KAAI,IAAI,MAAM,EAEZ,YAAW,OAAO,QAAQ;MACrB;EAEL,MAAM,MAAM,OAAO,QAAQ;AAC3B,aAAW,QAAQ,SACjB,YAAW;MAEX,YAAW,KAAK,UAAU,IAAI;CAEjC;AAGH,QAAO;AACR;;;;;AAMD,SAAS,cAAcA,QAA2B;CAChD,MAAMC,UAAoB,CAAE;AAG5B,KAAI,OAAO,YAAY,OAAO,SAAS,SAAS,EAC9C,SAAQ,MAAM,YAAY,OAAO,SAAS,KAAK,IAAI,CAAC,EAAE;AAIxD,KAAI,OAAO,cAAc,OAAO,KAAK,OAAO,WAAW,CAAC,SAAS,EAC/D,SAAQ,MAAM,cAAc,KAAK,UAAU,OAAO,WAAW,CAAC,EAAE;AAIlE,SAAQ,MAAM,aAAa,IAAI,KAAK,OAAO,WAAW,aAAa,CAAC,EAAE;AAEtE,QAAO,QAAQ,SAAS,KAAK,MAAM,QAAQ,KAAK,KAAK,CAAC,IAAI;AAC3D;;;;;;;;;;;;;;;;;;;;;;;;AAyBD,SAAgB,uBACdC,SACmB;AAEnB,0BAAyB;CAEzB,MAAM,EACJ,YACA,iBAAiB,CAAE,GACpB,GAAG;CAGJ,MAAM,WAAW;EAAE,GAAG;EAA0B,GAAG;CAAgB;CAEnE,IAAIC,MAAiC;CACrC,MAAM,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAErE,MAAMC,OAA0B,CAACJ,WAAsB;AACrD,OAAK,KAAK;AACR,SAAM,IAAI,mBAAmB;AAC7B,OAAI;AACF,QAAI,YAAY;GACjB,SAAQ,OAAO;AACd,eAAW,MACT,uDACA,EAAE,MAAO,EACV;AACD,UAAM;AACN;GACD;EACF;EAGD,MAAM,UAAU,cAAc,OAAO;EACrC,MAAM,UAAU,cAAc,OAAO;EACrC,MAAM,cAAc,UAAU;EAG9B,MAAM,YAAY,uBAAuB,OAAO,MAAM;EACtD,MAAM,UAAU,SAAS,OAAO;AAGhC,MAAI,IACF,KAAI;AACF,OAAI,WAAW,WAAW,SAAS,YAAY;EAChD,SAAQ,OAAO;AACd,cAAW,MACT,iDACA,EAAE,MAAO,EACV;EACF;CAEJ;AAGD,MAAK,OAAO,WAAW,MAAM;AAC3B,MAAI,KAAK;AACP,OAAI,SAAS;AACb,SAAM;EACP;CACF;AAED,QAAO;AACR"}
1
+ {"version":3,"file":"sink.bun.js","names":["options: WindowsEventLogSinkOptions"],"sources":["../src/sink.bun.ts"],"sourcesContent":["import type { Sink } from \"@logtape/logtape\";\nimport { WindowsEventLogBunFFI } from \"./ffi.bun.ts\";\nimport { getWindowsEventLogSinkForFFI } from \"./sink.ts\";\nimport type { WindowsEventLogSinkOptions } from \"./types.ts\";\n\n/**\n * Creates a Windows Event Log sink for Bun environments using FFI.\n *\n * This implementation uses Bun's native Foreign Function Interface to directly\n * call Windows Event Log APIs, providing high performance logging optimized\n * for the Bun runtime.\n *\n * @param options Configuration options for the sink\n * @returns A LogTape sink that writes to Windows Event Log\n * @throws {WindowsPlatformError} If not running on Windows\n * @throws {WindowsEventLogError} If Event Log operations fail\n *\n * @example\n * ```typescript\n * import { getWindowsEventLogSink } from \"@logtape/windows-eventlog\";\n *\n * const sink = getWindowsEventLogSink({\n * sourceName: \"MyApp\"\n * });\n * ```\n *\n * @since 1.0.0\n */\nexport function getWindowsEventLogSink(\n options: WindowsEventLogSinkOptions,\n): Sink & Disposable {\n const ffi = new WindowsEventLogBunFFI();\n return getWindowsEventLogSinkForFFI(ffi, options);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,uBACdA,SACmB;CACnB,MAAM,MAAM,IAAI;AAChB,QAAO,6BAA6B,KAAK,QAAQ;AAClD"}
package/dist/sink.cjs ADDED
@@ -0,0 +1,84 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_types = require('./types.cjs');
3
+ const require_formatter = require('./formatter.cjs');
4
+ const require_platform = require('./platform.cjs');
5
+ const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
6
+
7
+ //#region src/sink.ts
8
+ /**
9
+ * Helper function to remove any trailing newline that the formatter may add
10
+ * to the string. When writing to the event log, we don't want newlines at the
11
+ * end of the message.
12
+ */
13
+ function stripTrailingNewline(s) {
14
+ if (s.length > 0 && s.at(s.length - 1) === "\n") return s.substring(0, s.length - 1);
15
+ else return s;
16
+ }
17
+ /**
18
+ * Creates a Windows Event Log sink, parameterized on the FFI implementation.
19
+ *
20
+ * @param {WindowsEventLogFFI} ffi Actual FFI implementation to use
21
+ * @param options Configuration options for the sink
22
+ * @returns A LogTape sink that writes to Windows Event Log
23
+ * @throws {WindowsPlatformError} If not running on Windows
24
+ * @throws {WindowsEventLogError} If Event Log operations fail
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * import { getWindowsEventLogSink } from "@logtape/windows-eventlog";
29
+ *
30
+ * const sink = getWindowsEventLogSink({
31
+ * sourceName: "MyApp"
32
+ * });
33
+ * ```
34
+ *
35
+ * @since 1.0.0
36
+ */
37
+ function getWindowsEventLogSinkForFFI(ffi, options) {
38
+ require_platform.validateWindowsPlatform();
39
+ const { sourceName, eventIdMapping = {} } = options;
40
+ const eventIds = {
41
+ ...require_types.DEFAULT_EVENT_ID_MAPPING,
42
+ ...eventIdMapping
43
+ };
44
+ const metaLogger = (0, __logtape_logtape.getLogger)([
45
+ "logtape",
46
+ "meta",
47
+ "windows-eventlog"
48
+ ]);
49
+ const sink = (record) => {
50
+ try {
51
+ ffi.initialize(sourceName);
52
+ } catch (error) {
53
+ metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
54
+ return;
55
+ }
56
+ const eventType = require_types.mapLogLevelToEventType(record.level);
57
+ const eventId = eventIds[record.level];
58
+ const formatter = options.formatter ?? require_formatter.defaultWindowsEventlogFormatter;
59
+ const fullMessage = stripTrailingNewline(formatter(record));
60
+ const parameters = eventId === require_types.NELOG_OEM_Code ? [
61
+ fullMessage,
62
+ "",
63
+ "",
64
+ "",
65
+ "",
66
+ "",
67
+ "",
68
+ "",
69
+ ""
70
+ ] : [fullMessage];
71
+ try {
72
+ ffi.writeEvent(eventType, eventId, parameters);
73
+ } catch (error) {
74
+ metaLogger.error("Failed to write to Windows Event Log: {error}", { error });
75
+ }
76
+ };
77
+ sink[Symbol.dispose] = () => {
78
+ ffi.dispose();
79
+ };
80
+ return sink;
81
+ }
82
+
83
+ //#endregion
84
+ exports.getWindowsEventLogSinkForFFI = getWindowsEventLogSinkForFFI;
@@ -1,50 +1,8 @@
1
- const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
- const require_types = require('./types.cjs');
3
- const require_platform = require('./platform.cjs');
1
+ const require_sink = require('./sink.cjs');
4
2
  const require_ffi_deno = require('./ffi.deno.cjs');
5
- const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
6
3
 
7
4
  //#region src/sink.deno.ts
8
5
  /**
9
- * Formats a log record message into a string suitable for Windows Event Log.
10
- * Combines the template and arguments into a readable message.
11
- */
12
- function formatMessage(record) {
13
- let message = "";
14
- for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
15
- else {
16
- const arg = record.message[i];
17
- if (typeof arg === "string") message += arg;
18
- else message += JSON.stringify(arg);
19
- }
20
- return message;
21
- }
22
- /**
23
- * Formats additional context information for the log entry.
24
- * Includes category, properties, and other metadata.
25
- */
26
- function formatContext(record) {
27
- const context = [];
28
- if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
29
- if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
30
- context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
31
- return context.length > 0 ? `\n\n${context.join("\n")}` : "";
32
- }
33
- /**
34
- * Maps LogTape log levels to Windows Event Log types.
35
- */
36
- function getEventType(level) {
37
- switch (level) {
38
- case "fatal":
39
- case "error": return require_ffi_deno.EVENTLOG_ERROR_TYPE;
40
- case "warning": return require_ffi_deno.EVENTLOG_WARNING_TYPE;
41
- case "info":
42
- case "debug":
43
- case "trace":
44
- default: return require_ffi_deno.EVENTLOG_INFORMATION_TYPE;
45
- }
46
- }
47
- /**
48
6
  * Creates a Windows Event Log sink for Deno environments using FFI.
49
7
  *
50
8
  * This implementation uses Deno's Foreign Function Interface to directly
@@ -68,47 +26,8 @@ function getEventType(level) {
68
26
  * @since 1.0.0
69
27
  */
70
28
  function getWindowsEventLogSink(options) {
71
- require_platform.validateWindowsPlatform();
72
- const { sourceName, eventIdMapping = {} } = options;
73
- const eventIds = {
74
- ...require_types.DEFAULT_EVENT_ID_MAPPING,
75
- ...eventIdMapping
76
- };
77
- let ffi = null;
78
- const metaLogger = (0, __logtape_logtape.getLogger)([
79
- "logtape",
80
- "meta",
81
- "windows-eventlog"
82
- ]);
83
- const sink = (record) => {
84
- if (!ffi) try {
85
- ffi = new require_ffi_deno.WindowsEventLogFFI(sourceName);
86
- ffi.initialize();
87
- } catch (error) {
88
- metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
89
- return;
90
- }
91
- const message = formatMessage(record);
92
- const context = formatContext(record);
93
- const fullMessage = message + context;
94
- const eventType = getEventType(record.level);
95
- const eventId = eventIds[record.level];
96
- try {
97
- ffi.writeEvent(eventType, eventId, fullMessage);
98
- } catch (error) {
99
- metaLogger.error("Failed to write {level} message to Windows Event Log: {error}", {
100
- level: record.level,
101
- error
102
- });
103
- }
104
- };
105
- sink[Symbol.dispose] = () => {
106
- if (ffi) {
107
- ffi.dispose();
108
- ffi = null;
109
- }
110
- };
111
- return sink;
29
+ const ffi = new require_ffi_deno.WindowsEventLogDenoFFI();
30
+ return require_sink.getWindowsEventLogSinkForFFI(ffi, options);
112
31
  }
113
32
 
114
33
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"sink.deno.d.cts","names":[],"sources":["../src/sink.deno.ts"],"sourcesContent":[],"mappings":";;;;;;;AAsGA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
1
+ {"version":3,"file":"sink.deno.d.cts","names":[],"sources":["../src/sink.deno.ts"],"sourcesContent":[],"mappings":";;;;;;;AA4BA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"sink.deno.d.ts","names":[],"sources":["../src/sink.deno.ts"],"sourcesContent":[],"mappings":";;;;;;;AAsGA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
1
+ {"version":3,"file":"sink.deno.d.ts","names":[],"sources":["../src/sink.deno.ts"],"sourcesContent":[],"mappings":";;;;;;;AA4BA;;;;;AAEoB;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
package/dist/sink.deno.js CHANGED
@@ -1,49 +1,8 @@
1
- import { DEFAULT_EVENT_ID_MAPPING } from "./types.js";
2
- import { validateWindowsPlatform } from "./platform.js";
3
- import { EVENTLOG_ERROR_TYPE, EVENTLOG_INFORMATION_TYPE, EVENTLOG_WARNING_TYPE, WindowsEventLogFFI } from "./ffi.deno.js";
4
- import { getLogger } from "@logtape/logtape";
1
+ import { getWindowsEventLogSinkForFFI } from "./sink.js";
2
+ import { WindowsEventLogDenoFFI } from "./ffi.deno.js";
5
3
 
6
4
  //#region src/sink.deno.ts
7
5
  /**
8
- * Formats a log record message into a string suitable for Windows Event Log.
9
- * Combines the template and arguments into a readable message.
10
- */
11
- function formatMessage(record) {
12
- let message = "";
13
- for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
14
- else {
15
- const arg = record.message[i];
16
- if (typeof arg === "string") message += arg;
17
- else message += JSON.stringify(arg);
18
- }
19
- return message;
20
- }
21
- /**
22
- * Formats additional context information for the log entry.
23
- * Includes category, properties, and other metadata.
24
- */
25
- function formatContext(record) {
26
- const context = [];
27
- if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
28
- if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
29
- context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
30
- return context.length > 0 ? `\n\n${context.join("\n")}` : "";
31
- }
32
- /**
33
- * Maps LogTape log levels to Windows Event Log types.
34
- */
35
- function getEventType(level) {
36
- switch (level) {
37
- case "fatal":
38
- case "error": return EVENTLOG_ERROR_TYPE;
39
- case "warning": return EVENTLOG_WARNING_TYPE;
40
- case "info":
41
- case "debug":
42
- case "trace":
43
- default: return EVENTLOG_INFORMATION_TYPE;
44
- }
45
- }
46
- /**
47
6
  * Creates a Windows Event Log sink for Deno environments using FFI.
48
7
  *
49
8
  * This implementation uses Deno's Foreign Function Interface to directly
@@ -67,47 +26,8 @@ function getEventType(level) {
67
26
  * @since 1.0.0
68
27
  */
69
28
  function getWindowsEventLogSink(options) {
70
- validateWindowsPlatform();
71
- const { sourceName, eventIdMapping = {} } = options;
72
- const eventIds = {
73
- ...DEFAULT_EVENT_ID_MAPPING,
74
- ...eventIdMapping
75
- };
76
- let ffi = null;
77
- const metaLogger = getLogger([
78
- "logtape",
79
- "meta",
80
- "windows-eventlog"
81
- ]);
82
- const sink = (record) => {
83
- if (!ffi) try {
84
- ffi = new WindowsEventLogFFI(sourceName);
85
- ffi.initialize();
86
- } catch (error) {
87
- metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
88
- return;
89
- }
90
- const message = formatMessage(record);
91
- const context = formatContext(record);
92
- const fullMessage = message + context;
93
- const eventType = getEventType(record.level);
94
- const eventId = eventIds[record.level];
95
- try {
96
- ffi.writeEvent(eventType, eventId, fullMessage);
97
- } catch (error) {
98
- metaLogger.error("Failed to write {level} message to Windows Event Log: {error}", {
99
- level: record.level,
100
- error
101
- });
102
- }
103
- };
104
- sink[Symbol.dispose] = () => {
105
- if (ffi) {
106
- ffi.dispose();
107
- ffi = null;
108
- }
109
- };
110
- return sink;
29
+ const ffi = new WindowsEventLogDenoFFI();
30
+ return getWindowsEventLogSinkForFFI(ffi, options);
111
31
  }
112
32
 
113
33
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"sink.deno.js","names":["record: LogRecord","context: string[]","level: string","options: WindowsEventLogSinkOptions","ffi: WindowsEventLogFFI | null","sink: Sink & Disposable"],"sources":["../src/sink.deno.ts"],"sourcesContent":["import type { LogRecord, Sink } from \"@logtape/logtape\";\nimport { getLogger } from \"@logtape/logtape\";\nimport {\n EVENTLOG_ERROR_TYPE,\n EVENTLOG_INFORMATION_TYPE,\n EVENTLOG_WARNING_TYPE,\n WindowsEventLogFFI,\n} from \"./ffi.deno.ts\";\nimport { validateWindowsPlatform } from \"./platform.ts\";\nimport type { WindowsEventLogSinkOptions } from \"./types.ts\";\nimport { DEFAULT_EVENT_ID_MAPPING } from \"./types.ts\";\n\n/**\n * Formats a log record message into a string suitable for Windows Event Log.\n * Combines the template and arguments into a readable message.\n */\nfunction formatMessage(record: LogRecord): string {\n let message = \"\";\n\n // Combine template parts with arguments\n for (let i = 0; i < record.message.length; i++) {\n if (i % 2 === 0) {\n // Template part\n message += record.message[i];\n } else {\n // Argument - serialize it\n const arg = record.message[i];\n if (typeof arg === \"string\") {\n message += arg;\n } else {\n message += JSON.stringify(arg);\n }\n }\n }\n\n return message;\n}\n\n/**\n * Formats additional context information for the log entry.\n * Includes category, properties, and other metadata.\n */\nfunction formatContext(record: LogRecord): string {\n const context: string[] = [];\n\n // Add category if present\n if (record.category && record.category.length > 0) {\n context.push(`Category: ${record.category.join(\".\")}`);\n }\n\n // Add properties if present\n if (record.properties && Object.keys(record.properties).length > 0) {\n context.push(`Properties: ${JSON.stringify(record.properties)}`);\n }\n\n // Add timestamp\n context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);\n\n return context.length > 0 ? `\\n\\n${context.join(\"\\n\")}` : \"\";\n}\n\n/**\n * Maps LogTape log levels to Windows Event Log types.\n */\nfunction getEventType(level: string): number {\n switch (level) {\n case \"fatal\":\n case \"error\":\n return EVENTLOG_ERROR_TYPE;\n case \"warning\":\n return EVENTLOG_WARNING_TYPE;\n case \"info\":\n case \"debug\":\n case \"trace\":\n default:\n return EVENTLOG_INFORMATION_TYPE;\n }\n}\n\n/**\n * Creates a Windows Event Log sink for Deno environments using FFI.\n *\n * This implementation uses Deno's Foreign Function Interface to directly\n * call Windows Event Log APIs, providing reliable Event Log integration\n * without depending on external packages.\n *\n * @param options Configuration options for the sink\n * @returns A LogTape sink that writes to Windows Event Log\n * @throws {WindowsPlatformError} If not running on Windows\n * @throws {WindowsEventLogError} If Event Log operations fail\n *\n * @example\n * ```typescript\n * import { getWindowsEventLogSink } from \"@logtape/windows-eventlog\";\n *\n * const sink = getWindowsEventLogSink({\n * sourceName: \"MyApp\"\n * });\n * ```\n *\n * @since 1.0.0\n */\nexport function getWindowsEventLogSink(\n options: WindowsEventLogSinkOptions,\n): Sink & Disposable {\n // Validate platform early\n validateWindowsPlatform();\n\n const {\n sourceName,\n eventIdMapping = {},\n } = options;\n\n // Merge with default event ID mapping\n const eventIds = { ...DEFAULT_EVENT_ID_MAPPING, ...eventIdMapping };\n\n let ffi: WindowsEventLogFFI | null = null;\n const metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n const sink: Sink & Disposable = (record: LogRecord) => {\n // Initialize FFI if needed\n if (!ffi) {\n try {\n ffi = new WindowsEventLogFFI(sourceName);\n ffi.initialize();\n } catch (error) {\n metaLogger.error(\n \"Failed to initialize Windows Event Log FFI: {error}\",\n { error },\n );\n return; // Skip this log record\n }\n }\n\n // Format the complete message\n const message = formatMessage(record);\n const context = formatContext(record);\n const fullMessage = message + context;\n\n // Get event type and ID for this log level\n const eventType = getEventType(record.level);\n const eventId = eventIds[record.level];\n\n // Write to Event Log\n try {\n ffi.writeEvent(eventType, eventId, fullMessage);\n } catch (error) {\n metaLogger.error(\n \"Failed to write {level} message to Windows Event Log: {error}\",\n { level: record.level, error },\n );\n }\n };\n\n // Implement Disposable for cleanup\n sink[Symbol.dispose] = () => {\n // Clean up FFI resources\n if (ffi) {\n ffi.dispose();\n ffi = null;\n }\n };\n\n return sink;\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAS,cAAcA,QAA2B;CAChD,IAAI,UAAU;AAGd,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,QAAQ,IACzC,KAAI,IAAI,MAAM,EAEZ,YAAW,OAAO,QAAQ;MACrB;EAEL,MAAM,MAAM,OAAO,QAAQ;AAC3B,aAAW,QAAQ,SACjB,YAAW;MAEX,YAAW,KAAK,UAAU,IAAI;CAEjC;AAGH,QAAO;AACR;;;;;AAMD,SAAS,cAAcA,QAA2B;CAChD,MAAMC,UAAoB,CAAE;AAG5B,KAAI,OAAO,YAAY,OAAO,SAAS,SAAS,EAC9C,SAAQ,MAAM,YAAY,OAAO,SAAS,KAAK,IAAI,CAAC,EAAE;AAIxD,KAAI,OAAO,cAAc,OAAO,KAAK,OAAO,WAAW,CAAC,SAAS,EAC/D,SAAQ,MAAM,cAAc,KAAK,UAAU,OAAO,WAAW,CAAC,EAAE;AAIlE,SAAQ,MAAM,aAAa,IAAI,KAAK,OAAO,WAAW,aAAa,CAAC,EAAE;AAEtE,QAAO,QAAQ,SAAS,KAAK,MAAM,QAAQ,KAAK,KAAK,CAAC,IAAI;AAC3D;;;;AAKD,SAAS,aAAaC,OAAuB;AAC3C,SAAQ,OAAR;EACE,KAAK;EACL,KAAK,QACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,QACE,QAAO;CACV;AACF;;;;;;;;;;;;;;;;;;;;;;;;AAyBD,SAAgB,uBACdC,SACmB;AAEnB,0BAAyB;CAEzB,MAAM,EACJ,YACA,iBAAiB,CAAE,GACpB,GAAG;CAGJ,MAAM,WAAW;EAAE,GAAG;EAA0B,GAAG;CAAgB;CAEnE,IAAIC,MAAiC;CACrC,MAAM,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAErE,MAAMC,OAA0B,CAACL,WAAsB;AAErD,OAAK,IACH,KAAI;AACF,SAAM,IAAI,mBAAmB;AAC7B,OAAI,YAAY;EACjB,SAAQ,OAAO;AACd,cAAW,MACT,uDACA,EAAE,MAAO,EACV;AACD;EACD;EAIH,MAAM,UAAU,cAAc,OAAO;EACrC,MAAM,UAAU,cAAc,OAAO;EACrC,MAAM,cAAc,UAAU;EAG9B,MAAM,YAAY,aAAa,OAAO,MAAM;EAC5C,MAAM,UAAU,SAAS,OAAO;AAGhC,MAAI;AACF,OAAI,WAAW,WAAW,SAAS,YAAY;EAChD,SAAQ,OAAO;AACd,cAAW,MACT,iEACA;IAAE,OAAO,OAAO;IAAO;GAAO,EAC/B;EACF;CACF;AAGD,MAAK,OAAO,WAAW,MAAM;AAE3B,MAAI,KAAK;AACP,OAAI,SAAS;AACb,SAAM;EACP;CACF;AAED,QAAO;AACR"}
1
+ {"version":3,"file":"sink.deno.js","names":["options: WindowsEventLogSinkOptions"],"sources":["../src/sink.deno.ts"],"sourcesContent":["import type { Sink } from \"@logtape/logtape\";\nimport { WindowsEventLogDenoFFI } from \"./ffi.deno.ts\";\nimport { getWindowsEventLogSinkForFFI } from \"./sink.ts\";\nimport type { WindowsEventLogSinkOptions } from \"./types.ts\";\n\n/**\n * Creates a Windows Event Log sink for Deno environments using FFI.\n *\n * This implementation uses Deno's Foreign Function Interface to directly\n * call Windows Event Log APIs, providing reliable Event Log integration\n * without depending on external packages.\n *\n * @param options Configuration options for the sink\n * @returns A LogTape sink that writes to Windows Event Log\n * @throws {WindowsPlatformError} If not running on Windows\n * @throws {WindowsEventLogError} If Event Log operations fail\n *\n * @example\n * ```typescript\n * import { getWindowsEventLogSink } from \"@logtape/windows-eventlog\";\n *\n * const sink = getWindowsEventLogSink({\n * sourceName: \"MyApp\"\n * });\n * ```\n *\n * @since 1.0.0\n */\nexport function getWindowsEventLogSink(\n options: WindowsEventLogSinkOptions,\n): Sink & Disposable {\n const ffi = new WindowsEventLogDenoFFI();\n return getWindowsEventLogSinkForFFI(ffi, options);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,uBACdA,SACmB;CACnB,MAAM,MAAM,IAAI;AAChB,QAAO,6BAA6B,KAAK,QAAQ;AAClD"}
package/dist/sink.js ADDED
@@ -0,0 +1,84 @@
1
+ import { DEFAULT_EVENT_ID_MAPPING, NELOG_OEM_Code, mapLogLevelToEventType } from "./types.js";
2
+ import { defaultWindowsEventlogFormatter } from "./formatter.js";
3
+ import { validateWindowsPlatform } from "./platform.js";
4
+ import { getLogger } from "@logtape/logtape";
5
+
6
+ //#region src/sink.ts
7
+ /**
8
+ * Helper function to remove any trailing newline that the formatter may add
9
+ * to the string. When writing to the event log, we don't want newlines at the
10
+ * end of the message.
11
+ */
12
+ function stripTrailingNewline(s) {
13
+ if (s.length > 0 && s.at(s.length - 1) === "\n") return s.substring(0, s.length - 1);
14
+ else return s;
15
+ }
16
+ /**
17
+ * Creates a Windows Event Log sink, parameterized on the FFI implementation.
18
+ *
19
+ * @param {WindowsEventLogFFI} ffi Actual FFI implementation to use
20
+ * @param options Configuration options for the sink
21
+ * @returns A LogTape sink that writes to Windows Event Log
22
+ * @throws {WindowsPlatformError} If not running on Windows
23
+ * @throws {WindowsEventLogError} If Event Log operations fail
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * import { getWindowsEventLogSink } from "@logtape/windows-eventlog";
28
+ *
29
+ * const sink = getWindowsEventLogSink({
30
+ * sourceName: "MyApp"
31
+ * });
32
+ * ```
33
+ *
34
+ * @since 1.0.0
35
+ */
36
+ function getWindowsEventLogSinkForFFI(ffi, options) {
37
+ validateWindowsPlatform();
38
+ const { sourceName, eventIdMapping = {} } = options;
39
+ const eventIds = {
40
+ ...DEFAULT_EVENT_ID_MAPPING,
41
+ ...eventIdMapping
42
+ };
43
+ const metaLogger = getLogger([
44
+ "logtape",
45
+ "meta",
46
+ "windows-eventlog"
47
+ ]);
48
+ const sink = (record) => {
49
+ try {
50
+ ffi.initialize(sourceName);
51
+ } catch (error) {
52
+ metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
53
+ return;
54
+ }
55
+ const eventType = mapLogLevelToEventType(record.level);
56
+ const eventId = eventIds[record.level];
57
+ const formatter = options.formatter ?? defaultWindowsEventlogFormatter;
58
+ const fullMessage = stripTrailingNewline(formatter(record));
59
+ const parameters = eventId === NELOG_OEM_Code ? [
60
+ fullMessage,
61
+ "",
62
+ "",
63
+ "",
64
+ "",
65
+ "",
66
+ "",
67
+ "",
68
+ ""
69
+ ] : [fullMessage];
70
+ try {
71
+ ffi.writeEvent(eventType, eventId, parameters);
72
+ } catch (error) {
73
+ metaLogger.error("Failed to write to Windows Event Log: {error}", { error });
74
+ }
75
+ };
76
+ sink[Symbol.dispose] = () => {
77
+ ffi.dispose();
78
+ };
79
+ return sink;
80
+ }
81
+
82
+ //#endregion
83
+ export { getWindowsEventLogSinkForFFI };
84
+ //# sourceMappingURL=sink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink.js","names":["s: string","ffi: WindowsEventLogFFI","options: WindowsEventLogSinkOptions","sink: Sink & Disposable","record: LogRecord"],"sources":["../src/sink.ts"],"sourcesContent":["import type { LogRecord, Sink } from \"@logtape/logtape\";\nimport { getLogger } from \"@logtape/logtape\";\nimport type { WindowsEventLogFFI } from \"./ffi.ts\";\nimport { defaultWindowsEventlogFormatter } from \"./formatter.ts\";\nimport { validateWindowsPlatform } from \"./platform.ts\";\nimport {\n DEFAULT_EVENT_ID_MAPPING,\n mapLogLevelToEventType,\n NELOG_OEM_Code,\n type WindowsEventLogSinkOptions,\n} from \"./types.ts\";\n\n/**\n * Helper function to remove any trailing newline that the formatter may add\n * to the string. When writing to the event log, we don't want newlines at the\n * end of the message.\n */\nfunction stripTrailingNewline(s: string): string {\n if ((s.length > 0) && (s.at(s.length - 1) === \"\\n\")) {\n return s.substring(0, s.length - 1);\n } else {\n return s;\n }\n}\n\n/**\n * Creates a Windows Event Log sink, parameterized on the FFI implementation.\n *\n * @param {WindowsEventLogFFI} ffi Actual FFI implementation to use\n * @param options Configuration options for the sink\n * @returns A LogTape sink that writes to Windows Event Log\n * @throws {WindowsPlatformError} If not running on Windows\n * @throws {WindowsEventLogError} If Event Log operations fail\n *\n * @example\n * ```typescript\n * import { getWindowsEventLogSink } from \"@logtape/windows-eventlog\";\n *\n * const sink = getWindowsEventLogSink({\n * sourceName: \"MyApp\"\n * });\n * ```\n *\n * @since 1.0.0\n */\nexport function getWindowsEventLogSinkForFFI(\n ffi: WindowsEventLogFFI,\n options: WindowsEventLogSinkOptions,\n): Sink & Disposable {\n // Validate platform early\n validateWindowsPlatform();\n\n const {\n sourceName,\n eventIdMapping = {},\n } = options;\n\n // Merge with default event ID mapping\n const eventIds = { ...DEFAULT_EVENT_ID_MAPPING, ...eventIdMapping };\n\n const metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n const sink: Sink & Disposable = (record: LogRecord) => {\n try {\n ffi.initialize(sourceName);\n } catch (error) {\n metaLogger.error(\n \"Failed to initialize Windows Event Log FFI: {error}\",\n { error },\n );\n return;\n }\n\n // Get event type and ID for this log level\n const eventType = mapLogLevelToEventType(record.level);\n const eventId = eventIds[record.level];\n\n // Format the complete message using this function\n const formatter = options.formatter ?? defaultWindowsEventlogFormatter;\n const fullMessage = stripTrailingNewline(formatter(record));\n\n // If we are using the generic 3299 event (from netmsg.dll), then we need\n // to pass nine strings as placeholders instead of just one, or the\n // remaining placeholders themselves will be rendered into the text. This\n // assumes that we are not using that particular event ID together with\n // another string resource library.\n const parameters = (eventId === NELOG_OEM_Code)\n ? [fullMessage, \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\"]\n : [fullMessage];\n\n // Write to Event Log using FFI\n try {\n ffi.writeEvent(eventType, eventId, parameters);\n } catch (error) {\n metaLogger.error(\n \"Failed to write to Windows Event Log: {error}\",\n { error },\n );\n }\n };\n\n // Implement Disposable for cleanup\n sink[Symbol.dispose] = () => {\n ffi.dispose();\n };\n\n return sink;\n}\n"],"mappings":";;;;;;;;;;;AAiBA,SAAS,qBAAqBA,GAAmB;AAC/C,KAAK,EAAE,SAAS,KAAO,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,KAC5C,QAAO,EAAE,UAAU,GAAG,EAAE,SAAS,EAAE;KAEnC,QAAO;AAEV;;;;;;;;;;;;;;;;;;;;;AAsBD,SAAgB,6BACdC,KACAC,SACmB;AAEnB,0BAAyB;CAEzB,MAAM,EACJ,YACA,iBAAiB,CAAE,GACpB,GAAG;CAGJ,MAAM,WAAW;EAAE,GAAG;EAA0B,GAAG;CAAgB;CAEnE,MAAM,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAErE,MAAMC,OAA0B,CAACC,WAAsB;AACrD,MAAI;AACF,OAAI,WAAW,WAAW;EAC3B,SAAQ,OAAO;AACd,cAAW,MACT,uDACA,EAAE,MAAO,EACV;AACD;EACD;EAGD,MAAM,YAAY,uBAAuB,OAAO,MAAM;EACtD,MAAM,UAAU,SAAS,OAAO;EAGhC,MAAM,YAAY,QAAQ,aAAa;EACvC,MAAM,cAAc,qBAAqB,UAAU,OAAO,CAAC;EAO3D,MAAM,aAAc,YAAY,iBAC5B;GAAC;GAAa;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;EAAG,IAC7C,CAAC,WAAY;AAGjB,MAAI;AACF,OAAI,WAAW,WAAW,SAAS,WAAW;EAC/C,SAAQ,OAAO;AACd,cAAW,MACT,iDACA,EAAE,MAAO,EACV;EACF;CACF;AAGD,MAAK,OAAO,WAAW,MAAM;AAC3B,MAAI,SAAS;CACd;AAED,QAAO;AACR"}