@routier/core 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/LICENSE +21 -0
  2. package/{readme.md → README.md} +3 -3
  3. package/dist/assertions/index.cjs +191 -0
  4. package/dist/assertions/index.cjs.map +1 -0
  5. package/dist/assertions/index.js +43 -63
  6. package/dist/assertions/index.js.map +1 -1
  7. package/dist/capabilities/index.cjs +820 -0
  8. package/dist/capabilities/index.cjs.map +1 -0
  9. package/dist/capabilities/index.js +584 -558
  10. package/dist/capabilities/index.js.map +1 -1
  11. package/dist/codegen/handlers/CloneHandlerBuilder.d.ts +10 -1
  12. package/dist/codegen/handlers/clone/CloneArrayHandler.d.ts +3 -0
  13. package/dist/codegen/handlers/clone/CloneDateHandler.d.ts +13 -0
  14. package/dist/codegen/handlers/clone/CloneValueHandler.d.ts +16 -0
  15. package/dist/codegen/handlers/compare/CompareComputedHandler.d.ts +10 -0
  16. package/dist/codegen/handlers/compare/CompareFunctionHandler.d.ts +10 -0
  17. package/dist/codegen/handlers/deserialize/DeserializeArrayHandler.d.ts +14 -0
  18. package/dist/codegen/handlers/enableChangeTracking/EnableChangeTrackingArrayHandler.d.ts +11 -0
  19. package/dist/codegen/handlers/enrichment/EnrichmentArrayHandler.d.ts +11 -0
  20. package/dist/codegen/handlers/freeze/FreezeArrayHandler.d.ts +6 -0
  21. package/dist/codegen/handlers/hash/HashArrayHandler.d.ts +10 -0
  22. package/dist/codegen/handlers/hash/HashFileHandler.d.ts +24 -0
  23. package/dist/codegen/handlers/hash/HashObjectHandler.d.ts +10 -0
  24. package/dist/codegen/handlers/hash/HashTransformHandler.d.ts +23 -0
  25. package/dist/codegen/handlers/merge/MergeArrayHandler.d.ts +20 -0
  26. package/dist/codegen/handlers/merge/MergeObjectHandler.d.ts +10 -0
  27. package/dist/codegen/handlers/serialize/SerializeArrayHandler.d.ts +19 -0
  28. package/dist/codegen/handlers/strip/StripComputedHandler.d.ts +10 -0
  29. package/dist/codegen/handlers/strip/StripFunctionHandler.d.ts +9 -0
  30. package/dist/codegen/handlers/types.d.ts +55 -1
  31. package/dist/codegen/index.cjs +618 -0
  32. package/dist/codegen/index.cjs.map +1 -0
  33. package/dist/codegen/index.js +99 -127
  34. package/dist/codegen/index.js.map +1 -1
  35. package/dist/collections/MemoryDataCollection.d.ts +15 -1
  36. package/dist/collections/TagCollection.d.ts +0 -1
  37. package/dist/collections/index.cjs +702 -0
  38. package/dist/collections/index.cjs.map +1 -0
  39. package/dist/collections/index.js +282 -276
  40. package/dist/collections/index.js.map +1 -1
  41. package/dist/errors/OptimisticConcurrencyError.d.ts +18 -0
  42. package/dist/errors/PluginDestroyedError.d.ts +10 -0
  43. package/dist/errors/index.cjs +132 -0
  44. package/dist/errors/index.cjs.map +1 -0
  45. package/dist/errors/index.d.ts +2 -0
  46. package/dist/errors/index.js +61 -19
  47. package/dist/errors/index.js.map +1 -1
  48. package/dist/expressions/evaluate.d.ts +53 -0
  49. package/dist/expressions/index.cjs +2087 -0
  50. package/dist/expressions/index.cjs.map +1 -0
  51. package/dist/expressions/index.d.ts +1 -1
  52. package/dist/expressions/index.js +1727 -1082
  53. package/dist/expressions/index.js.map +1 -1
  54. package/dist/expressions/parser.d.ts +19 -0
  55. package/dist/expressions/types.d.ts +87 -2
  56. package/dist/index.cjs +14377 -0
  57. package/dist/index.cjs.map +1 -0
  58. package/dist/index.js +12374 -7931
  59. package/dist/index.js.map +1 -1
  60. package/dist/performance/index.cjs +217 -0
  61. package/dist/performance/index.cjs.map +1 -0
  62. package/dist/performance/index.js +120 -55
  63. package/dist/performance/index.js.map +1 -1
  64. package/dist/pipeline/index.cjs +576 -0
  65. package/dist/pipeline/index.cjs.map +1 -0
  66. package/dist/pipeline/index.js +223 -161
  67. package/dist/pipeline/index.js.map +1 -1
  68. package/dist/plugins/BatchingDbPlugin.d.ts +139 -0
  69. package/dist/plugins/CacheDbPlugin.d.ts +70 -0
  70. package/dist/plugins/ConcurrencyDbPlugin.d.ts +78 -0
  71. package/dist/plugins/EphemeralDataPlugin.d.ts +57 -1
  72. package/dist/plugins/RetryDbPlugin.d.ts +77 -0
  73. package/dist/plugins/index.cjs +6551 -0
  74. package/dist/plugins/index.cjs.map +1 -0
  75. package/dist/plugins/index.d.ts +5 -0
  76. package/dist/plugins/index.js +6271 -1170
  77. package/dist/plugins/index.js.map +1 -1
  78. package/dist/plugins/query/QueryOptionsCollection.d.ts +34 -0
  79. package/dist/plugins/query/explain.d.ts +82 -0
  80. package/dist/plugins/query/formatExplanation.d.ts +9 -0
  81. package/dist/plugins/query/index.d.ts +4 -0
  82. package/dist/plugins/query/join.d.ts +210 -0
  83. package/dist/plugins/query/similarity.d.ts +38 -0
  84. package/dist/plugins/query/types.d.ts +75 -1
  85. package/dist/plugins/translators/DataTranslator.d.ts +28 -0
  86. package/dist/plugins/translators/JsonTranslator.d.ts +27 -0
  87. package/dist/plugins/translators/SqlTranslator.d.ts +45 -0
  88. package/dist/plugins/translators/TupleTranslator.d.ts +45 -0
  89. package/dist/plugins/translators/index.d.ts +1 -0
  90. package/dist/plugins/types.d.ts +125 -3
  91. package/dist/plugins/wire/handler.d.ts +122 -0
  92. package/dist/plugins/wire/index.d.ts +4 -0
  93. package/dist/plugins/wire/persist.d.ts +43 -0
  94. package/dist/plugins/wire/query.d.ts +49 -0
  95. package/dist/plugins/wire/types.d.ts +139 -0
  96. package/dist/results/index.cjs +174 -0
  97. package/dist/results/index.cjs.map +1 -0
  98. package/dist/results/index.js +29 -44
  99. package/dist/results/index.js.map +1 -1
  100. package/dist/schema/PropertyInfo.d.ts +31 -2
  101. package/dist/schema/SchemaDefinition.d.ts +23 -1
  102. package/dist/schema/builder.d.ts +35 -1
  103. package/dist/schema/communication/broadcast.d.ts +17 -1
  104. package/dist/schema/index.cjs +6911 -0
  105. package/dist/schema/index.cjs.map +1 -0
  106. package/dist/schema/index.d.ts +2 -0
  107. package/dist/schema/index.js +5330 -4541
  108. package/dist/schema/index.js.map +1 -1
  109. package/dist/schema/property/base/SchemaBase.d.ts +48 -2
  110. package/dist/schema/property/modifiers/SchemaNullable.d.ts +10 -0
  111. package/dist/schema/property/modifiers/SchemaOptional.d.ts +19 -0
  112. package/dist/schema/property/modifiers/SchemaSearchable.d.ts +34 -0
  113. package/dist/schema/property/modifiers/index.d.ts +1 -0
  114. package/dist/schema/property/types/SchemaFile.d.ts +60 -0
  115. package/dist/schema/property/types/SchemaString.d.ts +21 -1
  116. package/dist/schema/property/types/SchemaVector.d.ts +61 -0
  117. package/dist/schema/property/types/index.d.ts +2 -0
  118. package/dist/schema/table/SchemaTransform.d.ts +40 -0
  119. package/dist/schema/table/index.d.ts +1 -0
  120. package/dist/schema/types.d.ts +166 -8
  121. package/dist/schema/utils/propertyKind.d.ts +4 -0
  122. package/dist/types/index.cjs +23 -0
  123. package/dist/types/index.cjs.map +1 -0
  124. package/dist/types/index.js +0 -14
  125. package/dist/types/index.js.map +1 -1
  126. package/dist/utilities/index.cjs +1013 -0
  127. package/dist/utilities/index.cjs.map +1 -0
  128. package/dist/utilities/index.js +541 -379
  129. package/dist/utilities/index.js.map +1 -1
  130. package/dist/utilities/logger.d.ts +48 -0
  131. package/package.json +156 -98
  132. package/dist/codegen/SlotPath.test.d.ts +0 -1
  133. package/dist/codegen/blocks.test.d.ts +0 -1
  134. package/dist/codegen/utils.test.d.ts +0 -1
  135. package/dist/collections/Changes.test.d.ts +0 -1
  136. package/dist/collections/IdSet.test.d.ts +0 -1
  137. package/dist/collections/MemoryDataCollection.test.d.ts +0 -1
  138. package/dist/collections/TagCollection.contract.test.d.ts +0 -1
  139. package/dist/collections/TagCollection.test.d.ts +0 -1
  140. package/dist/expressions/parser.test.d.ts +0 -1
  141. package/dist/expressions/sql.d.ts +0 -28
  142. package/dist/expressions/sql.test.d.ts +0 -1
  143. package/dist/expressions/utils.test.d.ts +0 -1
  144. package/dist/pipeline/SyncronousQueue.test.d.ts +0 -1
  145. package/dist/plugins/EphemeralDataPlugin.test.d.ts +0 -1
  146. package/dist/plugins/query/Query.test.d.ts +0 -1
  147. package/dist/plugins/query/QueryOptionsCollection.test.d.ts +0 -1
  148. package/dist/plugins/translators/JsonTranslator.test.d.ts +0 -1
  149. package/dist/plugins/translators/SqlTranslator.test.d.ts +0 -1
  150. package/dist/plugins/translators/TranslatedValues.test.d.ts +0 -1
  151. package/dist/results/Result.test.d.ts +0 -1
  152. package/dist/results/utils.test.d.ts +0 -1
  153. package/dist/schema/PropertyInfo.test.d.ts +0 -1
  154. package/dist/schema/communication/broadcast.test.d.ts +0 -1
  155. package/dist/schema/schemaGeneration.test.d.ts +0 -1
  156. package/dist/schema/utils/standardJsonSchema.test.d.ts +0 -1
  157. package/dist/utilities/arrays.test.d.ts +0 -1
  158. package/dist/utilities/dates.test.d.ts +0 -1
  159. package/dist/utilities/runtime.test.d.ts +0 -1
  160. package/dist/utilities/strings.test.d.ts +0 -1
  161. package/dist/utilities/uuid.test.d.ts +0 -1
@@ -0,0 +1,217 @@
1
+ (() => {
2
+ "use strict";
3
+ var __webpack_modules__ = ({
4
+ 581(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
5
+ __webpack_require__.d(__webpack_exports__, {
6
+ vF: () => (logger)
7
+ });
8
+ /**
9
+ * Levelled logging, resolved once.
10
+ *
11
+ * Three things about the previous implementation drove this shape:
12
+ *
13
+ * - **There was no way to turn logging off.** `globalThis.__ROUTIER_DEBUG__` was only ever
14
+ * compared against `true`, so setting it to `false` did nothing — while
15
+ * `docs/how-to/debug-logging.md` documented exactly that as the way to force logging off.
16
+ * A documented switch that silently does nothing is worse than no switch.
17
+ * - **`NODE_ENV === 'test'` enabled it.** Every Jest run therefore logged, because Jest always
18
+ * sets `NODE_ENV=test`. Measured on the S7 stress scenario, which drives ~2,000 saves through
19
+ * a plugin that logs three lines per query: 12.4s with logging, ~6s without. Test runners also
20
+ * capture console output by snapshotting a stack trace per call, so the cost is far above what
21
+ * writing to a terminal would suggest — and the output buries whatever the failure was.
22
+ * - **It was all-or-nothing, and re-resolved per call.** An error could not be kept while debug
23
+ * was dropped, and every one of the ~97 call sites re-read `globalThis` and `process.env`.
24
+ *
25
+ * Levels are compared numerically against a value cached at module load. Measured against a
26
+ * no-op console at 200k calls: an enabled call costs ~70ns, a call rejected by the gate ~3ns.
27
+ * Building the arguments the call site passes in accounts for ~0.2ns of that 3ns, which is why
28
+ * this keeps the ordinary `logger.debug(msg, payload)` signature instead of taking a thunk —
29
+ * a lazy API would recover 0.3% of an enabled call's cost and would have to change every call
30
+ * site to do it.
31
+ */ /** Ordered from most severe to most verbose. `silent` discards everything. */ const LOG_LEVELS = [
32
+ 'silent',
33
+ 'error',
34
+ 'warn',
35
+ 'info',
36
+ 'debug'
37
+ ];
38
+ /** Numeric rank, so a gate is one integer comparison. */ const RANK = {
39
+ silent: 0,
40
+ error: 1,
41
+ warn: 2,
42
+ info: 3,
43
+ debug: 4
44
+ };
45
+ const isLogLevel = (value)=>typeof value === 'string' && LOG_LEVELS.includes(value);
46
+ /**
47
+ * Resolves the configured level, in precedence order.
48
+ *
49
+ * Ordered most specific first: an explicit level beats a boolean flag, a boolean flag beats an
50
+ * environment variable, and an environment variable beats an inference from `NODE_ENV`. Anything
51
+ * unrecognised is ignored rather than treated as an error — a typo'd level should not take down
52
+ * an application, and `silent` is the safe direction to fall back to.
53
+ */ const resolveLevel = ()=>{
54
+ if (typeof globalThis !== 'undefined') {
55
+ const g = globalThis;
56
+ if (isLogLevel(g.__ROUTIER_LOG_LEVEL__)) {
57
+ return g.__ROUTIER_LOG_LEVEL__;
58
+ }
59
+ // Both directions honoured. `=== false` used to fall through to the NODE_ENV checks
60
+ // below and re-enable the logging it was asked to suppress.
61
+ if (g.__ROUTIER_DEBUG__ === true) return 'debug';
62
+ if (g.__ROUTIER_DEBUG__ === false) return 'silent';
63
+ }
64
+ // There is deliberately no `import.meta.env` branch, although the documentation used to
65
+ // promise one. It could never work: this package is bundled with rspack, which replaces
66
+ // `import.meta` with `undefined`, so the check would read the *library's* build-time
67
+ // environment rather than the application's — and referencing `import.meta` at all is a parse
68
+ // error under a CommonJS build target, which is how the test suite loads this file. Vite and
69
+ // similar apps set `__ROUTIER_LOG_LEVEL__` or `__ROUTIER_DEBUG__` from their own
70
+ // `import.meta.env`, which is what the docs now describe.
71
+ if (typeof process !== 'undefined' && process.env != null) {
72
+ if (isLogLevel(process.env.ROUTIER_LOG_LEVEL)) {
73
+ return process.env.ROUTIER_LOG_LEVEL;
74
+ }
75
+ const debug = process.env.DEBUG;
76
+ if (debug === 'routier' || debug === '*') return 'debug';
77
+ const env = "production"?.toLowerCase();
78
+ // `test` is deliberately absent. It used to be here, which meant no test suite anywhere
79
+ // could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test
80
+ // needs the output.
81
+ if (env === 'dev' || env === 'development') return 'debug';
82
+ }
83
+ return 'silent';
84
+ };
85
+ let level = resolveLevel();
86
+ let rank = RANK[level];
87
+ /**
88
+ * Overrides the level for the rest of the process.
89
+ *
90
+ * The configuration above is read once, at import, which is what makes the gate cheap — but it
91
+ * also means an application that decides its verbosity after startup, or a test that wants to
92
+ * assert on output, has no way in. This is that way in.
93
+ */ const setLogLevel = (next)=>{
94
+ if (isLogLevel(next) === false) {
95
+ throw new Error(`Unknown log level "${next}". Expected one of: ${LOG_LEVELS.join(', ')}`);
96
+ }
97
+ level = next;
98
+ rank = RANK[next];
99
+ };
100
+ const getLogLevel = ()=>level;
101
+ /** Re-reads the environment. For tests that change it after this module was imported. */ const resetLogLevel = ()=>{
102
+ level = resolveLevel();
103
+ rank = RANK[level];
104
+ };
105
+ /**
106
+ * Whether a message at this level would be emitted.
107
+ *
108
+ * For the rare call site whose *arguments* are expensive to build — a serialization, a deep
109
+ * clone, a join over a large collection. An ordinary payload object is not worth guarding; see
110
+ * the measurement in the header.
111
+ */ const isLogLevelEnabled = (at)=>rank >= RANK[at];
112
+ const emit = (at, method, args)=>{
113
+ if (rank < RANK[at]) {
114
+ return;
115
+ }
116
+ // Resolved at call time rather than captured once: test harnesses and browser devtools both
117
+ // replace console methods after modules have loaded, and a captured reference would keep
118
+ // writing past the replacement.
119
+ console[method](...args);
120
+ };
121
+ const logger = {
122
+ /** General-purpose output. Carried at `info`, since `log` names a console method, not a level. */ log: (...args)=>emit('info', 'log', args),
123
+ info: (...args)=>emit('info', 'info', args),
124
+ warn: (...args)=>emit('warn', 'warn', args),
125
+ error: (...args)=>emit('error', 'error', args),
126
+ debug: (...args)=>emit('debug', 'debug', args),
127
+ /** Diagnostic tabular output; verbose by nature, so it sits at `debug`. */ table: (...args)=>emit('debug', 'table', args)
128
+ };
129
+
130
+
131
+ },
132
+
133
+ });
134
+ // The module cache
135
+ var __webpack_module_cache__ = {};
136
+
137
+ // The require function
138
+ function __webpack_require__(moduleId) {
139
+
140
+ // Check if module is in cache
141
+ var cachedModule = __webpack_module_cache__[moduleId];
142
+ if (cachedModule !== undefined) {
143
+ return cachedModule.exports;
144
+ }
145
+ // Create a new module (and put it into the cache)
146
+ var module = (__webpack_module_cache__[moduleId] = {
147
+ exports: {}
148
+ });
149
+ // Execute the module function
150
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
151
+
152
+ // Return the exports of the module
153
+ return module.exports;
154
+
155
+ }
156
+
157
+ // webpack/runtime/define_property_getters
158
+ (() => {
159
+ __webpack_require__.d = (exports, definition) => {
160
+ for(var key in definition) {
161
+ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
162
+ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
163
+ }
164
+ }
165
+ };
166
+ })();
167
+ // webpack/runtime/has_own_property
168
+ (() => {
169
+ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
170
+ })();
171
+ // webpack/runtime/make_namespace_object
172
+ (() => {
173
+ // define __esModule on exports
174
+ __webpack_require__.r = (exports) => {
175
+ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
176
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
177
+ }
178
+ Object.defineProperty(exports, '__esModule', { value: true });
179
+ };
180
+ })();
181
+ var __webpack_exports__ = {};
182
+ // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
183
+ (() => {
184
+ __webpack_require__.r(__webpack_exports__);
185
+ __webpack_require__.d(__webpack_exports__, {
186
+ measure: () => (measure),
187
+ now: () => (now)
188
+ });
189
+ /* import */ var _utilities__rspack_import_0 = __webpack_require__(581);
190
+
191
+ const measurements = {};
192
+ const now = ()=>{
193
+ if (typeof performance !== 'undefined' && performance.now) {
194
+ // Browser or modern Node.js
195
+ return performance.now();
196
+ }
197
+ // Fallback for older environments
198
+ return Date.now();
199
+ };
200
+ const measure = {
201
+ start: (name)=>{
202
+ measurements[name] = now();
203
+ },
204
+ end: (name)=>{
205
+ const start = measurements[name];
206
+ delete measurements[name];
207
+ const delta = now() - start;
208
+ _utilities__rspack_import_0/* .logger.log */.vF.log(`[ROUTIER] - Performance: ${name} took ${delta}`);
209
+ }
210
+ };
211
+
212
+ })();
213
+
214
+ module.exports = __webpack_exports__;
215
+ })()
216
+ ;
217
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance/index.cjs","sources":["webpack://@routier/core/./src/utilities/logger.ts","webpack://@routier/core/webpack/runtime/define_property_getters","webpack://@routier/core/webpack/runtime/has_own_property","webpack://@routier/core/webpack/runtime/make_namespace_object","webpack://@routier/core/./src/performance/index.ts"],"sourcesContent":["/**\n * Levelled logging, resolved once.\n *\n * Three things about the previous implementation drove this shape:\n *\n * - **There was no way to turn logging off.** `globalThis.__ROUTIER_DEBUG__` was only ever\n * compared against `true`, so setting it to `false` did nothing — while\n * `docs/how-to/debug-logging.md` documented exactly that as the way to force logging off.\n * A documented switch that silently does nothing is worse than no switch.\n * - **`NODE_ENV === 'test'` enabled it.** Every Jest run therefore logged, because Jest always\n * sets `NODE_ENV=test`. Measured on the S7 stress scenario, which drives ~2,000 saves through\n * a plugin that logs three lines per query: 12.4s with logging, ~6s without. Test runners also\n * capture console output by snapshotting a stack trace per call, so the cost is far above what\n * writing to a terminal would suggest — and the output buries whatever the failure was.\n * - **It was all-or-nothing, and re-resolved per call.** An error could not be kept while debug\n * was dropped, and every one of the ~97 call sites re-read `globalThis` and `process.env`.\n *\n * Levels are compared numerically against a value cached at module load. Measured against a\n * no-op console at 200k calls: an enabled call costs ~70ns, a call rejected by the gate ~3ns.\n * Building the arguments the call site passes in accounts for ~0.2ns of that 3ns, which is why\n * this keeps the ordinary `logger.debug(msg, payload)` signature instead of taking a thunk —\n * a lazy API would recover 0.3% of an enabled call's cost and would have to change every call\n * site to do it.\n */\n\n/** Ordered from most severe to most verbose. `silent` discards everything. */\nexport const LOG_LEVELS = ['silent', 'error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\n/** Numeric rank, so a gate is one integer comparison. */\nconst RANK: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst isLogLevel = (value: unknown): value is LogLevel =>\n typeof value === 'string' && (LOG_LEVELS as readonly string[]).includes(value);\n\n/**\n * Resolves the configured level, in precedence order.\n *\n * Ordered most specific first: an explicit level beats a boolean flag, a boolean flag beats an\n * environment variable, and an environment variable beats an inference from `NODE_ENV`. Anything\n * unrecognised is ignored rather than treated as an error — a typo'd level should not take down\n * an application, and `silent` is the safe direction to fall back to.\n */\nconst resolveLevel = (): LogLevel => {\n if (typeof globalThis !== 'undefined') {\n const g = globalThis as { __ROUTIER_LOG_LEVEL__?: unknown; __ROUTIER_DEBUG__?: unknown };\n\n if (isLogLevel(g.__ROUTIER_LOG_LEVEL__)) {\n return g.__ROUTIER_LOG_LEVEL__;\n }\n\n // Both directions honoured. `=== false` used to fall through to the NODE_ENV checks\n // below and re-enable the logging it was asked to suppress.\n if (g.__ROUTIER_DEBUG__ === true) return 'debug';\n if (g.__ROUTIER_DEBUG__ === false) return 'silent';\n }\n\n // There is deliberately no `import.meta.env` branch, although the documentation used to\n // promise one. It could never work: this package is bundled with rspack, which replaces\n // `import.meta` with `undefined`, so the check would read the *library's* build-time\n // environment rather than the application's — and referencing `import.meta` at all is a parse\n // error under a CommonJS build target, which is how the test suite loads this file. Vite and\n // similar apps set `__ROUTIER_LOG_LEVEL__` or `__ROUTIER_DEBUG__` from their own\n // `import.meta.env`, which is what the docs now describe.\n if (typeof process !== 'undefined' && process.env != null) {\n if (isLogLevel(process.env.ROUTIER_LOG_LEVEL)) {\n return process.env.ROUTIER_LOG_LEVEL as LogLevel;\n }\n\n const debug = process.env.DEBUG;\n if (debug === 'routier' || debug === '*') return 'debug';\n\n const env = process.env.NODE_ENV?.toLowerCase();\n\n // `test` is deliberately absent. It used to be here, which meant no test suite anywhere\n // could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test\n // needs the output.\n if (env === 'dev' || env === 'development') return 'debug';\n }\n\n return 'silent';\n};\n\nlet level: LogLevel = resolveLevel();\nlet rank = RANK[level];\n\n/**\n * Overrides the level for the rest of the process.\n *\n * The configuration above is read once, at import, which is what makes the gate cheap — but it\n * also means an application that decides its verbosity after startup, or a test that wants to\n * assert on output, has no way in. This is that way in.\n */\nexport const setLogLevel = (next: LogLevel): void => {\n if (isLogLevel(next) === false) {\n throw new Error(`Unknown log level \"${next}\". Expected one of: ${LOG_LEVELS.join(', ')}`);\n }\n\n level = next;\n rank = RANK[next];\n};\n\nexport const getLogLevel = (): LogLevel => level;\n\n/** Re-reads the environment. For tests that change it after this module was imported. */\nexport const resetLogLevel = (): void => {\n level = resolveLevel();\n rank = RANK[level];\n};\n\n/**\n * Whether a message at this level would be emitted.\n *\n * For the rare call site whose *arguments* are expensive to build — a serialization, a deep\n * clone, a join over a large collection. An ordinary payload object is not worth guarding; see\n * the measurement in the header.\n */\nexport const isLogLevelEnabled = (at: LogLevel): boolean => rank >= RANK[at];\n\ntype ConsoleMethod = 'log' | 'info' | 'warn' | 'error' | 'debug' | 'table';\n\nconst emit = (at: LogLevel, method: ConsoleMethod, args: unknown[]) => {\n if (rank < RANK[at]) {\n return;\n }\n\n // Resolved at call time rather than captured once: test harnesses and browser devtools both\n // replace console methods after modules have loaded, and a captured reference would keep\n // writing past the replacement.\n (console[method] as (...a: unknown[]) => void)(...args);\n};\n\nexport const logger = {\n /** General-purpose output. Carried at `info`, since `log` names a console method, not a level. */\n log: (...args: unknown[]): void => emit('info', 'log', args),\n info: (...args: unknown[]): void => emit('info', 'info', args),\n warn: (...args: unknown[]): void => emit('warn', 'warn', args),\n error: (...args: unknown[]): void => emit('error', 'error', args),\n debug: (...args: unknown[]): void => emit('debug', 'debug', args),\n /** Diagnostic tabular output; verbose by nature, so it sits at `debug`. */\n table: (...args: unknown[]): void => emit('debug', 'table', args),\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { logger } from \"../utilities\";\n\nconst measurements: Record<string, number> = {}\n\nexport const now = (): number => {\n if (typeof performance !== 'undefined' && performance.now) {\n // Browser or modern Node.js\n return performance.now();\n }\n\n // Fallback for older environments\n return Date.now();\n}\n\nexport const measure = {\n start: (name: string): void => {\n measurements[name] = now();\n },\n end: (name: string): void => {\n const start = measurements[name];\n\n delete measurements[name];\n\n const delta = now() - start;\n\n logger.log(`[ROUTIER] - Performance: ${name} took ${delta}`);\n }\n}"],"names":["LOG_LEVELS","RANK","isLogLevel","value","resolveLevel","globalThis","g","process","debug","env","level","rank","setLogLevel","next","Error","getLogLevel","resetLogLevel","isLogLevelEnabled","at","emit","method","args","console","logger","measurements","now","performance","Date","measure","name","start","delta"],"mappings":"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"}
@@ -1,52 +1,128 @@
1
1
  var __webpack_modules__ = ({
2
- "./src/utilities/logger.ts"(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
3
- __webpack_require__.r(__webpack_exports__);
2
+ 581(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
4
3
  __webpack_require__.d(__webpack_exports__, {
5
- logger: () => (logger)
4
+ vF: () => (logger)
6
5
  });
7
6
  /**
8
- * Enable logging by setting `globalThis.__ROUTIER_DEBUG__ = true` before any routier code runs.
9
- */
10
- const shouldLog = () => {
7
+ * Levelled logging, resolved once.
8
+ *
9
+ * Three things about the previous implementation drove this shape:
10
+ *
11
+ * - **There was no way to turn logging off.** `globalThis.__ROUTIER_DEBUG__` was only ever
12
+ * compared against `true`, so setting it to `false` did nothing — while
13
+ * `docs/how-to/debug-logging.md` documented exactly that as the way to force logging off.
14
+ * A documented switch that silently does nothing is worse than no switch.
15
+ * - **`NODE_ENV === 'test'` enabled it.** Every Jest run therefore logged, because Jest always
16
+ * sets `NODE_ENV=test`. Measured on the S7 stress scenario, which drives ~2,000 saves through
17
+ * a plugin that logs three lines per query: 12.4s with logging, ~6s without. Test runners also
18
+ * capture console output by snapshotting a stack trace per call, so the cost is far above what
19
+ * writing to a terminal would suggest — and the output buries whatever the failure was.
20
+ * - **It was all-or-nothing, and re-resolved per call.** An error could not be kept while debug
21
+ * was dropped, and every one of the ~97 call sites re-read `globalThis` and `process.env`.
22
+ *
23
+ * Levels are compared numerically against a value cached at module load. Measured against a
24
+ * no-op console at 200k calls: an enabled call costs ~70ns, a call rejected by the gate ~3ns.
25
+ * Building the arguments the call site passes in accounts for ~0.2ns of that 3ns, which is why
26
+ * this keeps the ordinary `logger.debug(msg, payload)` signature instead of taking a thunk —
27
+ * a lazy API would recover 0.3% of an enabled call's cost and would have to change every call
28
+ * site to do it.
29
+ */ /** Ordered from most severe to most verbose. `silent` discards everything. */ const LOG_LEVELS = [
30
+ 'silent',
31
+ 'error',
32
+ 'warn',
33
+ 'info',
34
+ 'debug'
35
+ ];
36
+ /** Numeric rank, so a gate is one integer comparison. */ const RANK = {
37
+ silent: 0,
38
+ error: 1,
39
+ warn: 2,
40
+ info: 3,
41
+ debug: 4
42
+ };
43
+ const isLogLevel = (value)=>typeof value === 'string' && LOG_LEVELS.includes(value);
44
+ /**
45
+ * Resolves the configured level, in precedence order.
46
+ *
47
+ * Ordered most specific first: an explicit level beats a boolean flag, a boolean flag beats an
48
+ * environment variable, and an environment variable beats an inference from `NODE_ENV`. Anything
49
+ * unrecognised is ignored rather than treated as an error — a typo'd level should not take down
50
+ * an application, and `silent` is the safe direction to fall back to.
51
+ */ const resolveLevel = ()=>{
11
52
  if (typeof globalThis !== 'undefined') {
12
53
  const g = globalThis;
13
- if (g.__ROUTIER_DEBUG__ === true)
14
- return true;
54
+ if (isLogLevel(g.__ROUTIER_LOG_LEVEL__)) {
55
+ return g.__ROUTIER_LOG_LEVEL__;
56
+ }
57
+ // Both directions honoured. `=== false` used to fall through to the NODE_ENV checks
58
+ // below and re-enable the logging it was asked to suppress.
59
+ if (g.__ROUTIER_DEBUG__ === true) return 'debug';
60
+ if (g.__ROUTIER_DEBUG__ === false) return 'silent';
15
61
  }
62
+ // There is deliberately no `import.meta.env` branch, although the documentation used to
63
+ // promise one. It could never work: this package is bundled with rspack, which replaces
64
+ // `import.meta` with `undefined`, so the check would read the *library's* build-time
65
+ // environment rather than the application's — and referencing `import.meta` at all is a parse
66
+ // error under a CommonJS build target, which is how the test suite loads this file. Vite and
67
+ // similar apps set `__ROUTIER_LOG_LEVEL__` or `__ROUTIER_DEBUG__` from their own
68
+ // `import.meta.env`, which is what the docs now describe.
16
69
  if (typeof process !== 'undefined' && process.env != null) {
70
+ if (isLogLevel(process.env.ROUTIER_LOG_LEVEL)) {
71
+ return process.env.ROUTIER_LOG_LEVEL;
72
+ }
17
73
  const debug = process.env.DEBUG;
18
- if (debug === 'routier' || debug === '*')
19
- return true;
20
- const env = "development"?.toLowerCase();
21
- if (env === 'dev' || env === 'development' || env === 'test')
22
- return true;
74
+ if (debug === 'routier' || debug === '*') return 'debug';
75
+ const env = "production"?.toLowerCase();
76
+ // `test` is deliberately absent. It used to be here, which meant no test suite anywhere
77
+ // could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test
78
+ // needs the output.
79
+ if (env === 'dev' || env === 'development') return 'debug';
23
80
  }
24
- return false;
81
+ return 'silent';
25
82
  };
26
- const tryLog = (type, ...args) => {
27
- if (shouldLog()) {
28
- console[type](...args);
83
+ let level = resolveLevel();
84
+ let rank = RANK[level];
85
+ /**
86
+ * Overrides the level for the rest of the process.
87
+ *
88
+ * The configuration above is read once, at import, which is what makes the gate cheap — but it
89
+ * also means an application that decides its verbosity after startup, or a test that wants to
90
+ * assert on output, has no way in. This is that way in.
91
+ */ const setLogLevel = (next)=>{
92
+ if (isLogLevel(next) === false) {
93
+ throw new Error(`Unknown log level "${next}". Expected one of: ${LOG_LEVELS.join(', ')}`);
94
+ }
95
+ level = next;
96
+ rank = RANK[next];
97
+ };
98
+ const getLogLevel = ()=>level;
99
+ /** Re-reads the environment. For tests that change it after this module was imported. */ const resetLogLevel = ()=>{
100
+ level = resolveLevel();
101
+ rank = RANK[level];
102
+ };
103
+ /**
104
+ * Whether a message at this level would be emitted.
105
+ *
106
+ * For the rare call site whose *arguments* are expensive to build — a serialization, a deep
107
+ * clone, a join over a large collection. An ordinary payload object is not worth guarding; see
108
+ * the measurement in the header.
109
+ */ const isLogLevelEnabled = (at)=>rank >= RANK[at];
110
+ const emit = (at, method, args)=>{
111
+ if (rank < RANK[at]) {
112
+ return;
29
113
  }
114
+ // Resolved at call time rather than captured once: test harnesses and browser devtools both
115
+ // replace console methods after modules have loaded, and a captured reference would keep
116
+ // writing past the replacement.
117
+ console[method](...args);
30
118
  };
31
119
  const logger = {
32
- log: (...args) => {
33
- tryLog("log", ...args);
34
- },
35
- info: (...args) => {
36
- tryLog("info", ...args);
37
- },
38
- warn: (...args) => {
39
- tryLog("warn", ...args);
40
- },
41
- error: (...args) => {
42
- tryLog("error", ...args);
43
- },
44
- debug: (...args) => {
45
- tryLog("debug", ...args);
46
- },
47
- table: (...args) => {
48
- tryLog("table", ...args);
49
- },
120
+ /** General-purpose output. Carried at `info`, since `log` names a console method, not a level. */ log: (...args)=>emit('info', 'log', args),
121
+ info: (...args)=>emit('info', 'info', args),
122
+ warn: (...args)=>emit('warn', 'warn', args),
123
+ error: (...args)=>emit('error', 'error', args),
124
+ debug: (...args)=>emit('debug', 'debug', args),
125
+ /** Diagnostic tabular output; verbose by nature, so it sits at `debug`. */ table: (...args)=>emit('debug', 'table', args)
50
126
  };
51
127
 
52
128
 
@@ -90,28 +166,17 @@ __webpack_require__.d = (exports, definition) => {
90
166
  (() => {
91
167
  __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
92
168
  })();
93
- // webpack/runtime/make_namespace_object
94
- (() => {
95
- // define __esModule on exports
96
- __webpack_require__.r = (exports) => {
97
- if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
98
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
99
- }
100
- Object.defineProperty(exports, '__esModule', { value: true });
101
- };
102
- })();
103
169
  var __webpack_exports__ = {};
104
170
  // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
105
171
  (() => {
106
- __webpack_require__.r(__webpack_exports__);
107
172
  __webpack_require__.d(__webpack_exports__, {
108
- measure: () => (measure),
109
- now: () => (now)
173
+ t: () => (now),
174
+ x: () => (measure)
110
175
  });
111
- /* import */ var _utilities__rspack_import_0 = __webpack_require__("./src/utilities/logger.ts");
176
+ /* import */ var _utilities__rspack_import_0 = __webpack_require__(581);
112
177
 
113
178
  const measurements = {};
114
- const now = () => {
179
+ const now = ()=>{
115
180
  if (typeof performance !== 'undefined' && performance.now) {
116
181
  // Browser or modern Node.js
117
182
  return performance.now();
@@ -120,21 +185,21 @@ const now = () => {
120
185
  return Date.now();
121
186
  };
122
187
  const measure = {
123
- start: (name) => {
188
+ start: (name)=>{
124
189
  measurements[name] = now();
125
190
  },
126
- end: (name) => {
191
+ end: (name)=>{
127
192
  const start = measurements[name];
128
193
  delete measurements[name];
129
194
  const delta = now() - start;
130
- _utilities__rspack_import_0.logger.log(`[ROUTIER] - Performance: ${name} took ${delta}`);
195
+ _utilities__rspack_import_0/* .logger.log */.vF.log(`[ROUTIER] - Performance: ${name} took ${delta}`);
131
196
  }
132
197
  };
133
198
 
134
199
  })();
135
200
 
136
- var __webpack_exports__measure = __webpack_exports__.measure;
137
- var __webpack_exports__now = __webpack_exports__.now;
201
+ var __webpack_exports__measure = __webpack_exports__.x;
202
+ var __webpack_exports__now = __webpack_exports__.t;
138
203
  export { __webpack_exports__measure as measure, __webpack_exports__now as now };
139
204
 
140
205
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"performance/index.js","sources":["webpack://@routier/core/./src/utilities/logger.ts","webpack://@routier/core/webpack/runtime/define_property_getters","webpack://@routier/core/webpack/runtime/has_own_property","webpack://@routier/core/webpack/runtime/make_namespace_object","webpack://@routier/core/./src/performance/index.ts"],"sourcesContent":["/**\n * Enable logging by setting `globalThis.__ROUTIER_DEBUG__ = true` before any routier code runs.\n */\nconst shouldLog = (): boolean => {\n if (typeof globalThis !== 'undefined') {\n const g = globalThis as { __ROUTIER_DEBUG__?: boolean };\n if (g.__ROUTIER_DEBUG__ === true) return true;\n }\n\n if (typeof process !== 'undefined' && process.env != null) {\n const debug = process.env.DEBUG;\n if (debug === 'routier' || debug === '*') return true;\n const env = process.env.NODE_ENV?.toLowerCase();\n if (env === 'dev' || env === 'development' || env === 'test') return true;\n }\n\n return false;\n};\n\ntype LogMethods = \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\" | \"table\";\nconst tryLog = (type: LogMethods, ...args: unknown[]) => {\n if (shouldLog()) {\n (console[type] as (...args: unknown[]) => void)(...args);\n }\n};\n\nexport const logger = {\n log: (...args: unknown[]): void => {\n tryLog(\"log\", ...args);\n },\n info: (...args: unknown[]): void => {\n tryLog(\"info\", ...args);\n },\n warn: (...args: unknown[]): void => {\n tryLog(\"warn\", ...args);\n },\n error: (...args: unknown[]): void => {\n tryLog(\"error\", ...args);\n },\n debug: (...args: unknown[]): void => {\n tryLog(\"debug\", ...args);\n },\n table: (...args: unknown[]): void => {\n tryLog(\"table\", ...args);\n },\n};\n\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { logger } from \"../utilities\";\n\nconst measurements: Record<string, number> = {}\n\nexport const now = (): number => {\n if (typeof performance !== 'undefined' && performance.now) {\n // Browser or modern Node.js\n return performance.now();\n }\n\n // Fallback for older environments\n return Date.now();\n}\n\nexport const measure = {\n start: (name: string): void => {\n measurements[name] = now();\n },\n end: (name: string): void => {\n const start = measurements[name];\n\n delete measurements[name];\n\n const delta = now() - start;\n\n logger.log(`[ROUTIER] - Performance: ${name} took ${delta}`);\n }\n}"],"names":[],"mappings":";;;;;;AAAA;;GAEG;AACH,MAAM,SAAS,GAAG,GAAY,EAAE;IAC5B,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,UAA6C,CAAC;QACxD,IAAI,CAAC,CAAC,iBAAiB,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IAClD,CAAC;IAED,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QACtD,MAAM,GAAG,GAAG,aAAoB,EAAE,WAAW,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;IAC9E,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAGF,MAAM,MAAM,GAAG,CAAC,IAAgB,EAAE,GAAG,IAAe,EAAE,EAAE;IACpD,IAAI,SAAS,EAAE,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAkC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7D,CAAC;AACL,CAAC,CAAC;AAEK,MAAM,MAAM,GAAG;IAClB,GAAG,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAC9B,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAC/B,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAC/B,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,KAAK,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAChC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,KAAK,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAChC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,KAAK,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAChC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7B,CAAC;CACJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7CF;AACA;AACA;AACA,kDAAkD,wCAAwC;AAC1F;AACA;AACA,E;;;;ACNA,wF;;;;ACAA;AACA;AACA;AACA,uDAAuD,iBAAiB;AACxE;AACA,gDAAgD,aAAa;AAC7D,E;;;;;;;;;;;ACNsC;AAEtC,MAAM,YAAY,GAA2B,EAAE;AAExC,MAAM,GAAG,GAAG,GAAW,EAAE;IAC5B,IAAI,OAAO,WAAW,KAAK,WAAW,IAAI,WAAW,CAAC,GAAG,EAAE,CAAC;QACxD,4BAA4B;QAC5B,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,kCAAkC;IAClC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;AACtB,CAAC;AAEM,MAAM,OAAO,GAAG;IACnB,KAAK,EAAE,CAAC,IAAY,EAAQ,EAAE;QAC1B,YAAY,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;IAC/B,CAAC;IACD,GAAG,EAAE,CAAC,IAAY,EAAQ,EAAE;QACxB,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAEjC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAE1B,MAAM,KAAK,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC;QAE5B,sCAAU,CAAC,4BAA4B,IAAI,SAAS,KAAK,EAAE,CAAC,CAAC;IACjE,CAAC;CACJ"}
1
+ {"version":3,"file":"performance/index.js","sources":["webpack://@routier/core/./src/utilities/logger.ts","webpack://@routier/core/webpack/runtime/define_property_getters","webpack://@routier/core/webpack/runtime/has_own_property","webpack://@routier/core/./src/performance/index.ts"],"sourcesContent":["/**\n * Levelled logging, resolved once.\n *\n * Three things about the previous implementation drove this shape:\n *\n * - **There was no way to turn logging off.** `globalThis.__ROUTIER_DEBUG__` was only ever\n * compared against `true`, so setting it to `false` did nothing — while\n * `docs/how-to/debug-logging.md` documented exactly that as the way to force logging off.\n * A documented switch that silently does nothing is worse than no switch.\n * - **`NODE_ENV === 'test'` enabled it.** Every Jest run therefore logged, because Jest always\n * sets `NODE_ENV=test`. Measured on the S7 stress scenario, which drives ~2,000 saves through\n * a plugin that logs three lines per query: 12.4s with logging, ~6s without. Test runners also\n * capture console output by snapshotting a stack trace per call, so the cost is far above what\n * writing to a terminal would suggest — and the output buries whatever the failure was.\n * - **It was all-or-nothing, and re-resolved per call.** An error could not be kept while debug\n * was dropped, and every one of the ~97 call sites re-read `globalThis` and `process.env`.\n *\n * Levels are compared numerically against a value cached at module load. Measured against a\n * no-op console at 200k calls: an enabled call costs ~70ns, a call rejected by the gate ~3ns.\n * Building the arguments the call site passes in accounts for ~0.2ns of that 3ns, which is why\n * this keeps the ordinary `logger.debug(msg, payload)` signature instead of taking a thunk —\n * a lazy API would recover 0.3% of an enabled call's cost and would have to change every call\n * site to do it.\n */\n\n/** Ordered from most severe to most verbose. `silent` discards everything. */\nexport const LOG_LEVELS = ['silent', 'error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\n/** Numeric rank, so a gate is one integer comparison. */\nconst RANK: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst isLogLevel = (value: unknown): value is LogLevel =>\n typeof value === 'string' && (LOG_LEVELS as readonly string[]).includes(value);\n\n/**\n * Resolves the configured level, in precedence order.\n *\n * Ordered most specific first: an explicit level beats a boolean flag, a boolean flag beats an\n * environment variable, and an environment variable beats an inference from `NODE_ENV`. Anything\n * unrecognised is ignored rather than treated as an error — a typo'd level should not take down\n * an application, and `silent` is the safe direction to fall back to.\n */\nconst resolveLevel = (): LogLevel => {\n if (typeof globalThis !== 'undefined') {\n const g = globalThis as { __ROUTIER_LOG_LEVEL__?: unknown; __ROUTIER_DEBUG__?: unknown };\n\n if (isLogLevel(g.__ROUTIER_LOG_LEVEL__)) {\n return g.__ROUTIER_LOG_LEVEL__;\n }\n\n // Both directions honoured. `=== false` used to fall through to the NODE_ENV checks\n // below and re-enable the logging it was asked to suppress.\n if (g.__ROUTIER_DEBUG__ === true) return 'debug';\n if (g.__ROUTIER_DEBUG__ === false) return 'silent';\n }\n\n // There is deliberately no `import.meta.env` branch, although the documentation used to\n // promise one. It could never work: this package is bundled with rspack, which replaces\n // `import.meta` with `undefined`, so the check would read the *library's* build-time\n // environment rather than the application's — and referencing `import.meta` at all is a parse\n // error under a CommonJS build target, which is how the test suite loads this file. Vite and\n // similar apps set `__ROUTIER_LOG_LEVEL__` or `__ROUTIER_DEBUG__` from their own\n // `import.meta.env`, which is what the docs now describe.\n if (typeof process !== 'undefined' && process.env != null) {\n if (isLogLevel(process.env.ROUTIER_LOG_LEVEL)) {\n return process.env.ROUTIER_LOG_LEVEL as LogLevel;\n }\n\n const debug = process.env.DEBUG;\n if (debug === 'routier' || debug === '*') return 'debug';\n\n const env = process.env.NODE_ENV?.toLowerCase();\n\n // `test` is deliberately absent. It used to be here, which meant no test suite anywhere\n // could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test\n // needs the output.\n if (env === 'dev' || env === 'development') return 'debug';\n }\n\n return 'silent';\n};\n\nlet level: LogLevel = resolveLevel();\nlet rank = RANK[level];\n\n/**\n * Overrides the level for the rest of the process.\n *\n * The configuration above is read once, at import, which is what makes the gate cheap — but it\n * also means an application that decides its verbosity after startup, or a test that wants to\n * assert on output, has no way in. This is that way in.\n */\nexport const setLogLevel = (next: LogLevel): void => {\n if (isLogLevel(next) === false) {\n throw new Error(`Unknown log level \"${next}\". Expected one of: ${LOG_LEVELS.join(', ')}`);\n }\n\n level = next;\n rank = RANK[next];\n};\n\nexport const getLogLevel = (): LogLevel => level;\n\n/** Re-reads the environment. For tests that change it after this module was imported. */\nexport const resetLogLevel = (): void => {\n level = resolveLevel();\n rank = RANK[level];\n};\n\n/**\n * Whether a message at this level would be emitted.\n *\n * For the rare call site whose *arguments* are expensive to build — a serialization, a deep\n * clone, a join over a large collection. An ordinary payload object is not worth guarding; see\n * the measurement in the header.\n */\nexport const isLogLevelEnabled = (at: LogLevel): boolean => rank >= RANK[at];\n\ntype ConsoleMethod = 'log' | 'info' | 'warn' | 'error' | 'debug' | 'table';\n\nconst emit = (at: LogLevel, method: ConsoleMethod, args: unknown[]) => {\n if (rank < RANK[at]) {\n return;\n }\n\n // Resolved at call time rather than captured once: test harnesses and browser devtools both\n // replace console methods after modules have loaded, and a captured reference would keep\n // writing past the replacement.\n (console[method] as (...a: unknown[]) => void)(...args);\n};\n\nexport const logger = {\n /** General-purpose output. Carried at `info`, since `log` names a console method, not a level. */\n log: (...args: unknown[]): void => emit('info', 'log', args),\n info: (...args: unknown[]): void => emit('info', 'info', args),\n warn: (...args: unknown[]): void => emit('warn', 'warn', args),\n error: (...args: unknown[]): void => emit('error', 'error', args),\n debug: (...args: unknown[]): void => emit('debug', 'debug', args),\n /** Diagnostic tabular output; verbose by nature, so it sits at `debug`. */\n table: (...args: unknown[]): void => emit('debug', 'table', args),\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import { logger } from \"../utilities\";\n\nconst measurements: Record<string, number> = {}\n\nexport const now = (): number => {\n if (typeof performance !== 'undefined' && performance.now) {\n // Browser or modern Node.js\n return performance.now();\n }\n\n // Fallback for older environments\n return Date.now();\n}\n\nexport const measure = {\n start: (name: string): void => {\n measurements[name] = now();\n },\n end: (name: string): void => {\n const start = measurements[name];\n\n delete measurements[name];\n\n const delta = now() - start;\n\n logger.log(`[ROUTIER] - Performance: ${name} took ${delta}`);\n }\n}"],"names":["LOG_LEVELS","RANK","isLogLevel","value","resolveLevel","globalThis","g","process","debug","env","level","rank","setLogLevel","next","Error","getLogLevel","resetLogLevel","isLogLevelEnabled","at","emit","method","args","console","logger","measurements","now","performance","Date","measure","name","start","delta"],"mappings":"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"}