@zmdb/compiler 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +40 -0
  3. package/dist/codegen/index.d.ts +50 -0
  4. package/dist/codegen/index.d.ts.map +1 -0
  5. package/dist/codegen/index.js +364 -0
  6. package/dist/codegen/index.js.map +1 -0
  7. package/dist/codegen/scan.d.ts +105 -0
  8. package/dist/codegen/scan.d.ts.map +1 -0
  9. package/dist/codegen/scan.js +450 -0
  10. package/dist/codegen/scan.js.map +1 -0
  11. package/dist/codegen/witness.d.ts +76 -0
  12. package/dist/codegen/witness.d.ts.map +1 -0
  13. package/dist/codegen/witness.js +690 -0
  14. package/dist/codegen/witness.js.map +1 -0
  15. package/dist/config/contract.d.ts +41 -0
  16. package/dist/config/contract.d.ts.map +1 -0
  17. package/dist/config/contract.js +5 -0
  18. package/dist/config/contract.js.map +1 -0
  19. package/dist/config/index.d.ts +53 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +277 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/index.zmdb.generated.d.ts +12 -0
  24. package/dist/config/index.zmdb.generated.js +28 -0
  25. package/dist/config/index.zmdb.witness.d.ts +3 -0
  26. package/dist/config/index.zmdb.witness.d.ts.map +1 -0
  27. package/dist/config/index.zmdb.witness.js +20 -0
  28. package/dist/config/index.zmdb.witness.js.map +1 -0
  29. package/dist/configured-plugin.d.ts +11 -0
  30. package/dist/configured-plugin.d.ts.map +1 -0
  31. package/dist/configured-plugin.js +27 -0
  32. package/dist/configured-plugin.js.map +1 -0
  33. package/dist/emit/index.d.ts +103 -0
  34. package/dist/emit/index.d.ts.map +1 -0
  35. package/dist/emit/index.js +1356 -0
  36. package/dist/emit/index.js.map +1 -0
  37. package/dist/errors.d.ts +7 -0
  38. package/dist/errors.d.ts.map +1 -0
  39. package/dist/errors.js +2 -0
  40. package/dist/errors.js.map +1 -0
  41. package/dist/index.d.ts +46 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +254 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/lint/ast.d.ts +17 -0
  46. package/dist/lint/ast.d.ts.map +1 -0
  47. package/dist/lint/ast.js +77 -0
  48. package/dist/lint/ast.js.map +1 -0
  49. package/dist/lint/host-types.d.ts +9 -0
  50. package/dist/lint/host-types.d.ts.map +1 -0
  51. package/dist/lint/host-types.js +2 -0
  52. package/dist/lint/host-types.js.map +1 -0
  53. package/dist/lint/index.d.ts +23 -0
  54. package/dist/lint/index.d.ts.map +1 -0
  55. package/dist/lint/index.js +53 -0
  56. package/dist/lint/index.js.map +1 -0
  57. package/dist/lint/rules/no-distributed-nullable-tags.d.ts +3 -0
  58. package/dist/lint/rules/no-distributed-nullable-tags.d.ts.map +1 -0
  59. package/dist/lint/rules/no-distributed-nullable-tags.js +71 -0
  60. package/dist/lint/rules/no-distributed-nullable-tags.js.map +1 -0
  61. package/dist/lint/rules/no-empty-patch.d.ts +3 -0
  62. package/dist/lint/rules/no-empty-patch.d.ts.map +1 -0
  63. package/dist/lint/rules/no-empty-patch.js +26 -0
  64. package/dist/lint/rules/no-empty-patch.js.map +1 -0
  65. package/dist/lint/rules/no-interpolated-sql.d.ts +3 -0
  66. package/dist/lint/rules/no-interpolated-sql.d.ts.map +1 -0
  67. package/dist/lint/rules/no-interpolated-sql.js +35 -0
  68. package/dist/lint/rules/no-interpolated-sql.js.map +1 -0
  69. package/dist/lint/rules/no-unbounded-find.d.ts +3 -0
  70. package/dist/lint/rules/no-unbounded-find.d.ts.map +1 -0
  71. package/dist/lint/rules/no-unbounded-find.js +26 -0
  72. package/dist/lint/rules/no-unbounded-find.js.map +1 -0
  73. package/dist/lint/rules/no-unknown-json-column.d.ts +3 -0
  74. package/dist/lint/rules/no-unknown-json-column.d.ts.map +1 -0
  75. package/dist/lint/rules/no-unknown-json-column.js +35 -0
  76. package/dist/lint/rules/no-unknown-json-column.js.map +1 -0
  77. package/dist/lint/rules/require-sql-on-number.d.ts +3 -0
  78. package/dist/lint/rules/require-sql-on-number.d.ts.map +1 -0
  79. package/dist/lint/rules/require-sql-on-number.js +34 -0
  80. package/dist/lint/rules/require-sql-on-number.js.map +1 -0
  81. package/dist/lint/types.d.ts +12 -0
  82. package/dist/lint/types.d.ts.map +1 -0
  83. package/dist/lint/types.js +2 -0
  84. package/dist/lint/types.js.map +1 -0
  85. package/dist/metro/metro.d.ts +22 -0
  86. package/dist/metro/metro.d.ts.map +1 -0
  87. package/dist/metro/metro.js +242 -0
  88. package/dist/metro/metro.js.map +1 -0
  89. package/dist/protobuf/decode.d.ts +20 -0
  90. package/dist/protobuf/decode.d.ts.map +1 -0
  91. package/dist/protobuf/decode.js +289 -0
  92. package/dist/protobuf/decode.js.map +1 -0
  93. package/dist/protobuf/descriptor.d.ts +16 -0
  94. package/dist/protobuf/descriptor.d.ts.map +1 -0
  95. package/dist/protobuf/descriptor.js +303 -0
  96. package/dist/protobuf/descriptor.js.map +1 -0
  97. package/dist/protobuf/encode.d.ts +20 -0
  98. package/dist/protobuf/encode.d.ts.map +1 -0
  99. package/dist/protobuf/encode.js +203 -0
  100. package/dist/protobuf/encode.js.map +1 -0
  101. package/dist/protobuf/grpc-ir.d.ts +16 -0
  102. package/dist/protobuf/grpc-ir.d.ts.map +1 -0
  103. package/dist/protobuf/grpc-ir.js +2 -0
  104. package/dist/protobuf/grpc-ir.js.map +1 -0
  105. package/dist/protobuf/plan.d.ts +42 -0
  106. package/dist/protobuf/plan.d.ts.map +1 -0
  107. package/dist/protobuf/plan.js +158 -0
  108. package/dist/protobuf/plan.js.map +1 -0
  109. package/dist/reflect/callsites.d.ts +40 -0
  110. package/dist/reflect/callsites.d.ts.map +1 -0
  111. package/dist/reflect/callsites.js +153 -0
  112. package/dist/reflect/callsites.js.map +1 -0
  113. package/dist/reflect/index.d.ts +106 -0
  114. package/dist/reflect/index.d.ts.map +1 -0
  115. package/dist/reflect/index.js +1421 -0
  116. package/dist/reflect/index.js.map +1 -0
  117. package/dist/reflect/session.d.ts +118 -0
  118. package/dist/reflect/session.d.ts.map +1 -0
  119. package/dist/reflect/session.js +228 -0
  120. package/dist/reflect/session.js.map +1 -0
  121. package/dist/testing/index.d.ts +69 -0
  122. package/dist/testing/index.d.ts.map +1 -0
  123. package/dist/testing/index.js +210 -0
  124. package/dist/testing/index.js.map +1 -0
  125. package/dist/transform/index.d.ts +74 -0
  126. package/dist/transform/index.d.ts.map +1 -0
  127. package/dist/transform/index.js +572 -0
  128. package/dist/transform/index.js.map +1 -0
  129. package/dist/unplugin/index.d.ts +53 -0
  130. package/dist/unplugin/index.d.ts.map +1 -0
  131. package/dist/unplugin/index.js +130 -0
  132. package/dist/unplugin/index.js.map +1 -0
  133. package/dist/unplugin/inline-bench.d.ts +29 -0
  134. package/dist/unplugin/inline-bench.d.ts.map +1 -0
  135. package/dist/unplugin/inline-bench.js +82 -0
  136. package/dist/unplugin/inline-bench.js.map +1 -0
  137. package/package.json +110 -0
  138. package/src/codegen/index.ts +451 -0
  139. package/src/codegen/scan.ts +574 -0
  140. package/src/codegen/witness.ts +819 -0
  141. package/src/config/contract.ts +48 -0
  142. package/src/config/index.ts +384 -0
  143. package/src/config/index.zmdb.generated.d.ts +12 -0
  144. package/src/config/index.zmdb.generated.js +28 -0
  145. package/src/config/index.zmdb.witness.ts +22 -0
  146. package/src/configured-plugin.ts +35 -0
  147. package/src/emit/index.ts +1496 -0
  148. package/src/errors.ts +6 -0
  149. package/src/index.ts +336 -0
  150. package/src/lint/ast.ts +96 -0
  151. package/src/lint/host-types.ts +9 -0
  152. package/src/lint/index.ts +80 -0
  153. package/src/lint/rules/no-distributed-nullable-tags.ts +76 -0
  154. package/src/lint/rules/no-empty-patch.ts +26 -0
  155. package/src/lint/rules/no-interpolated-sql.ts +45 -0
  156. package/src/lint/rules/no-unbounded-find.ts +26 -0
  157. package/src/lint/rules/no-unknown-json-column.ts +36 -0
  158. package/src/lint/rules/require-sql-on-number.ts +34 -0
  159. package/src/lint/types.ts +11 -0
  160. package/src/metro/metro.ts +313 -0
  161. package/src/protobuf/decode.ts +375 -0
  162. package/src/protobuf/descriptor.ts +353 -0
  163. package/src/protobuf/encode.ts +277 -0
  164. package/src/protobuf/grpc-ir.ts +17 -0
  165. package/src/protobuf/plan.ts +244 -0
  166. package/src/reflect/callsites.ts +198 -0
  167. package/src/reflect/index.ts +1723 -0
  168. package/src/reflect/session.ts +276 -0
  169. package/src/testing/index.ts +298 -0
  170. package/src/transform/index.ts +690 -0
  171. package/src/unplugin/index.ts +182 -0
  172. package/src/unplugin/inline-bench.ts +92 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/unplugin/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE/F,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAClC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7D;;;;;;OAMG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACrD,QAAQ,CAAC,IAAI,IAAI,CAAC;CACnB;AAED,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAChD;AAED,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACnE;AAID,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,YAAY,CAqFlE"}
@@ -0,0 +1,130 @@
1
+ // The bundler hook. One compiler session per build, one transform per module.
2
+ //
3
+ // `enforce: 'pre'` is load-bearing rather than decorative. The transform rewrites by
4
+ // text offset against the positions the TypeScript compiler parsed, so it has to see
5
+ // the module before anything else edits it. Running late means `sourceFile.text !== code`
6
+ // and the whole file degrades to the tag-only path — silently faster to build and
7
+ // silently slower to run, which is the worst way for this to fail.
8
+ //
9
+ // The session is opened on the first module and held for the build (REQ-TF-11). Loading
10
+ // the project is the expensive half; a checker call is a cheap round-trip. A session per
11
+ // file would make the AOT path cost more than the runtime walker it replaces.
12
+ import { resolveNaming } from '@zmdb/schema/naming';
13
+ import { ReflectSession } from '../reflect/session.js';
14
+ import { transformCode, transformFile } from '../transform/index.js';
15
+ /** Inline `validate(tags.X(…), …)` with no compiler. Type arguments need `transformFile`. */
16
+ export function transformTypeChecks(code) {
17
+ return transformCode(code);
18
+ }
19
+ const SOURCE = /\.(?:ts|tsx|mts|cts|js|jsx|mjs)$/;
20
+ export function zmdbAot(options = {}) {
21
+ let session = options.session;
22
+ const reflect = { naming: resolveNaming(options.naming) };
23
+ /** Whether this plugin opened the session, and therefore has to close it. */
24
+ let owned = false;
25
+ /** Files already refreshed after a text mismatch, so the retry happens at most once. */
26
+ const retried = new Set();
27
+ const ensureSession = () => {
28
+ if (session)
29
+ return session;
30
+ if (options.project === undefined)
31
+ return undefined;
32
+ session = ReflectSession.open({ project: options.project, ...(options.cwd ? { cwd: options.cwd } : {}) });
33
+ owned = true;
34
+ return session;
35
+ };
36
+ return {
37
+ name: 'zmdb-aot',
38
+ enforce: 'pre',
39
+ transform(code, id) {
40
+ // Never dependencies and never declaration files: a package ships already-built
41
+ // JavaScript, and rewriting it would be rewriting someone else's compiled output.
42
+ if (id.includes('node_modules'))
43
+ return null;
44
+ if (id.endsWith('.d.ts') || !SOURCE.test(id))
45
+ return null;
46
+ const open = ensureSession();
47
+ if (!open) {
48
+ const out = transformCode(code);
49
+ return out === code ? null : { code: out };
50
+ }
51
+ // Workspace package exports point at source files, so a bundler can hand us a
52
+ // dependency whose path does not contain `node_modules`. The compiler still marks
53
+ // that file as an external library. Treat it exactly like an installed dependency:
54
+ // framework code ships its own build and must not be recompiled as consumer code.
55
+ const sourceFile = open.sourceFile(id);
56
+ if (sourceFile !== undefined && open.program.isSourceFileFromExternalLibrary(sourceFile))
57
+ return null;
58
+ let result = transformFile(id, code, {
59
+ session: open,
60
+ reflect,
61
+ ...(options.emit ? { emit: options.emit } : {}),
62
+ });
63
+ // A stale program is the likely cause of a text mismatch, and it is cheap to rule
64
+ // out: re-check this one file and try again. Once per file — if the text still
65
+ // disagrees, something else edited the module and no refresh will fix that.
66
+ if (isStale(result.diagnostics) && !retried.has(id)) {
67
+ retried.add(id);
68
+ // A module the program has never seen has to be announced as created; telling it a
69
+ // file it does not know about "changed" is a no-op.
70
+ if (open.sourceFile(id))
71
+ open.refresh([id]);
72
+ else
73
+ open.created([id]);
74
+ result = transformFile(id, code, {
75
+ session: open,
76
+ reflect,
77
+ ...(options.emit ? { emit: options.emit } : {}),
78
+ });
79
+ }
80
+ const refusals = result.diagnostics.filter(diagnostic => diagnostic.position !== undefined);
81
+ if (refusals.length > 0) {
82
+ if (options.onDiagnostic)
83
+ for (const refusal of refusals)
84
+ options.onDiagnostic(refusal);
85
+ else
86
+ throw new Error(formatRefusals(refusals));
87
+ }
88
+ return result.changed ? { code: result.code } : null;
89
+ },
90
+ watchChange(id, change) {
91
+ retried.delete(id);
92
+ if (!session)
93
+ return;
94
+ if (change?.event === 'create')
95
+ session.created([id]);
96
+ else if (change?.event === 'delete')
97
+ session.deleted([id]);
98
+ else
99
+ session.refresh([id]);
100
+ },
101
+ buildEnd() {
102
+ if (owned)
103
+ session?.close();
104
+ session = undefined;
105
+ owned = false;
106
+ retried.clear();
107
+ },
108
+ };
109
+ }
110
+ /**
111
+ * Whether the complaint was about the program's view of the file rather than the code.
112
+ *
113
+ * Both cases are recoverable and both are ordinary: the bundler is handing over a module
114
+ * the compiler has not read yet (a new file) or has read at an older revision (an edit).
115
+ * A refusal about a call site is not in here, because no amount of re-reading fixes it.
116
+ */
117
+ function isStale(diagnostics) {
118
+ return diagnostics.some(diagnostic => diagnostic.position === undefined &&
119
+ (diagnostic.reason.includes('not the text the compiler parsed') ||
120
+ diagnostic.reason.includes('not part of the TypeScript project')));
121
+ }
122
+ function formatRefusals(refusals) {
123
+ const lines = refusals.map(refusal => {
124
+ const where = refusal.path === '' ? '' : ` at \`${refusal.path}\``;
125
+ const printed = refusal.source === undefined ? '' : ` (${refusal.source})`;
126
+ return ` ${refusal.fileName}:${refusal.position ?? 0} — \`${refusal.callee ?? '?'}<T>\`${where}: ${refusal.reason}${printed}`;
127
+ });
128
+ return `@zmdb/compiler cannot compile ${refusals.length} call site(s):\n${lines.join('\n')}`;
129
+ }
130
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/unplugin/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Ops/sec for `fn` over `n` iterations, after a 10k-iteration warm-up.
3
+ *
4
+ * `fn` receives a rotating index and must return something derived from the work it did. Both
5
+ * halves matter — see the file header.
6
+ */
7
+ export declare function opsPerSecond(fn: (index: number) => unknown, n: number): number;
8
+ /**
9
+ * Ops per current-thread CPU second for an absolute performance floor.
10
+ *
11
+ * Unlike wall time, this clock does not advance while another test worker has descheduled the
12
+ * current one. The measured work remains synchronous JavaScript on this thread, so CPU time
13
+ * preserves the cost distinction while removing suite contention from the result.
14
+ */
15
+ export declare function threadCpuOpsPerSecond(fn: (index: number) => unknown, n: number): number;
16
+ /**
17
+ * The best of `trials` runs of `opsPerSecond(fn, n)`.
18
+ *
19
+ * For a *ratio* between two functions, one measurement each is not enough. A single timed loop
20
+ * here is tens of milliseconds long, and when vitest is running the whole suite across every
21
+ * core, one descheduling of that length is the difference between a 6x reading and a 4.6x one
22
+ * — which is exactly how the acceptance gate came to fail under load and pass in isolation.
23
+ *
24
+ * Best-of rather than a mean, because contention is one-sided: it can only ever make a
25
+ * function look slower than it is, never faster. The fastest of several runs is the closest
26
+ * available estimate of what the code itself does, which is what the gate is a claim about.
27
+ */
28
+ export declare function peakOpsPerSecond(fn: (index: number) => unknown, n: number, trials: number): number;
29
+ //# sourceMappingURL=inline-bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-bench.d.ts","sourceRoot":"","sources":["../../src/unplugin/inline-bench.ts"],"names":[],"mappings":"AA8CA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUvF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIlG"}
@@ -0,0 +1,82 @@
1
+ // The timing helper the AOT plugin benchmarks share.
2
+ //
3
+ // Both #82 (the build produces a working inlined validator) and #83 (the acceptance gate)
4
+ // time the emitted check against the runtime walker. Each used to carry its own copy of the
5
+ // loop, so a change to how "ops/sec" is measured would have had to be made twice for the
6
+ // two numbers to stay comparable.
7
+ //
8
+ // Building the validator no longer lives here. It used to, back when the transform was a
9
+ // text parser that needed nothing but a string; now it needs a compiler, and the project
10
+ // harness in `emit/__testing__/project.ts` is what owns that.
11
+ //
12
+ // A note on why the loops below look the way they do, since it is the whole reason these
13
+ // numbers mean anything. The measured function must be called for its *result*, and that
14
+ // result has to reach something observable. An earlier version timed `() => void check(input)`
15
+ // and discarded the boolean: for the inlined AOT check — a pure function of a hoisted constant
16
+ // — V8 eventually proves the call has no effect and deletes the loop body. That does not read
17
+ // as an error, it reads as 1.4 *billion* ops/sec, about 90x the honest figure, and it only
18
+ // appears once the function is fully optimized. So the fixed 200k-iteration single shot was
19
+ // getting a roughly truthful number by not running long enough to be optimized properly, and
20
+ // any attempt to measure it more carefully made it worse.
21
+ //
22
+ // Hence: `fn` returns a value, every return value is folded into a counter, and the counter is
23
+ // read afterwards. The input is also rotated, so the checked object is not a constant the
24
+ // optimizer can fold the property loads out of.
25
+ import { threadCpuUsage } from 'node:process';
26
+ function measuredOpsPerSecond(fn, n, now, ticksPerSecond) {
27
+ let sink = 0;
28
+ for (let i = 0; i < 10_000; i++)
29
+ if (fn(i))
30
+ sink++;
31
+ const start = now();
32
+ for (let i = 0; i < n; i++)
33
+ if (fn(i))
34
+ sink++;
35
+ const elapsed = now() - start;
36
+ // Reading `sink` is what keeps the calls that produced it alive. Without a use, the whole
37
+ // loop is dead code and a sufficiently good optimizer is entitled to say so.
38
+ if (sink < 0)
39
+ throw new Error('unreachable, and here to make the measured work observable');
40
+ return Math.round((n / elapsed) * ticksPerSecond);
41
+ }
42
+ /**
43
+ * Ops/sec for `fn` over `n` iterations, after a 10k-iteration warm-up.
44
+ *
45
+ * `fn` receives a rotating index and must return something derived from the work it did. Both
46
+ * halves matter — see the file header.
47
+ */
48
+ export function opsPerSecond(fn, n) {
49
+ return measuredOpsPerSecond(fn, n, () => performance.now(), 1000);
50
+ }
51
+ /**
52
+ * Ops per current-thread CPU second for an absolute performance floor.
53
+ *
54
+ * Unlike wall time, this clock does not advance while another test worker has descheduled the
55
+ * current one. The measured work remains synchronous JavaScript on this thread, so CPU time
56
+ * preserves the cost distinction while removing suite contention from the result.
57
+ */
58
+ export function threadCpuOpsPerSecond(fn, n) {
59
+ return measuredOpsPerSecond(fn, n, () => {
60
+ const usage = threadCpuUsage();
61
+ return usage.user + usage.system;
62
+ }, 1_000_000);
63
+ }
64
+ /**
65
+ * The best of `trials` runs of `opsPerSecond(fn, n)`.
66
+ *
67
+ * For a *ratio* between two functions, one measurement each is not enough. A single timed loop
68
+ * here is tens of milliseconds long, and when vitest is running the whole suite across every
69
+ * core, one descheduling of that length is the difference between a 6x reading and a 4.6x one
70
+ * — which is exactly how the acceptance gate came to fail under load and pass in isolation.
71
+ *
72
+ * Best-of rather than a mean, because contention is one-sided: it can only ever make a
73
+ * function look slower than it is, never faster. The fastest of several runs is the closest
74
+ * available estimate of what the code itself does, which is what the gate is a claim about.
75
+ */
76
+ export function peakOpsPerSecond(fn, n, trials) {
77
+ let best = 0;
78
+ for (let trial = 0; trial < trials; trial++)
79
+ best = Math.max(best, opsPerSecond(fn, n));
80
+ return best;
81
+ }
82
+ //# sourceMappingURL=inline-bench.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-bench.js","sourceRoot":"","sources":["../../src/unplugin/inline-bench.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,0FAA0F;AAC1F,4FAA4F;AAC5F,yFAAyF;AACzF,kCAAkC;AAClC,EAAE;AACF,yFAAyF;AACzF,yFAAyF;AACzF,8DAA8D;AAC9D,EAAE;AACF,yFAAyF;AACzF,yFAAyF;AACzF,+FAA+F;AAC/F,+FAA+F;AAC/F,8FAA8F;AAC9F,2FAA2F;AAC3F,4FAA4F;AAC5F,6FAA6F;AAC7F,0DAA0D;AAC1D,EAAE;AACF,+FAA+F;AAC/F,0FAA0F;AAC1F,gDAAgD;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C,SAAS,oBAAoB,CAC3B,EAA8B,EAC9B,CAAS,EACT,GAAiB,EACjB,cAAsB;IAEtB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAAE,IAAI,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAAE,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC;IAC9B,0FAA0F;IAC1F,6EAA6E;IAC7E,IAAI,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC5F,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,cAAc,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAA8B,EAAE,CAAS;IACpE,OAAO,oBAAoB,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAA8B,EAAE,CAAS;IAC7E,OAAO,oBAAoB,CACzB,EAAE,EACF,CAAC,EACD,GAAG,EAAE;QACH,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;IACnC,CAAC,EACD,SAAS,CACV,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAA8B,EAAE,CAAS,EAAE,MAAc;IACxF,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE;QAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACxF,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json ADDED
@@ -0,0 +1,110 @@
1
+ {
2
+ "name": "@zmdb/compiler",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "The single TypeScript front end for zmdb reflection, AOT emission, code generation, build adapters, lint rules, and project configuration.",
5
+ "keywords": [
6
+ "aot",
7
+ "codegen",
8
+ "compiler",
9
+ "reflection",
10
+ "typescript",
11
+ "validation",
12
+ "zmdb"
13
+ ],
14
+ "homepage": "https://github.com/ambasta/zmdb#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/ambasta/zmdb/issues"
17
+ },
18
+ "license": "GPL-3.0-or-later",
19
+ "author": "zmdb contributors",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/ambasta/zmdb.git",
23
+ "directory": "packages/compiler"
24
+ },
25
+ "type": "module",
26
+ "sideEffects": false,
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./config": {
33
+ "types": "./dist/config/index.d.ts",
34
+ "import": "./dist/config/index.js"
35
+ },
36
+ "./config/contract": {
37
+ "types": "./dist/config/contract.d.ts",
38
+ "import": "./dist/config/contract.js"
39
+ },
40
+ "./emit": {
41
+ "types": "./dist/emit/index.d.ts",
42
+ "import": "./dist/emit/index.js"
43
+ },
44
+ "./errors": {
45
+ "types": "./dist/errors.d.ts",
46
+ "import": "./dist/errors.js"
47
+ },
48
+ "./lint": {
49
+ "types": "./dist/lint/index.d.ts",
50
+ "import": "./dist/lint/index.js"
51
+ },
52
+ "./metro": {
53
+ "types": "./dist/metro/metro.d.ts",
54
+ "import": "./dist/metro/metro.js",
55
+ "require": "./dist/metro/metro.js"
56
+ },
57
+ "./reflect": {
58
+ "types": "./dist/reflect/index.d.ts",
59
+ "import": "./dist/reflect/index.js"
60
+ },
61
+ "./testing": {
62
+ "types": "./dist/testing/index.d.ts",
63
+ "import": "./dist/testing/index.js"
64
+ },
65
+ "./transform": {
66
+ "types": "./dist/transform/index.d.ts",
67
+ "import": "./dist/transform/index.js"
68
+ },
69
+ "./unplugin": {
70
+ "types": "./dist/unplugin/index.d.ts",
71
+ "import": "./dist/unplugin/index.js"
72
+ }
73
+ },
74
+ "publishConfig": {
75
+ "access": "public",
76
+ "tag": "beta"
77
+ },
78
+ "scripts": {
79
+ "build": "node ../../scripts/build-package.mjs",
80
+ "test": "vitest run"
81
+ },
82
+ "dependencies": {
83
+ "@zmdb/ai": "1.0.0-beta.1"
84
+ },
85
+ "peerDependencies": {
86
+ "@zmdb/schema": "1.0.0-beta.1",
87
+ "@zmdb/sql": "1.0.0-beta.1",
88
+ "@zmdb/validator": "1.0.0-beta.1",
89
+ "metro": ">=0.87.0 <0.88.0",
90
+ "metro-babel-transformer": ">=0.87.0 <0.88.0",
91
+ "oxlint": ">=1.81.0 <1.82.0",
92
+ "typescript": ">=7.0.2 <8.0.0"
93
+ },
94
+ "peerDependenciesMeta": {
95
+ "metro": {
96
+ "optional": true
97
+ },
98
+ "metro-babel-transformer": {
99
+ "optional": true
100
+ },
101
+ "oxlint": {
102
+ "optional": true
103
+ }
104
+ },
105
+ "engines": {
106
+ "node": ">=26"
107
+ },
108
+ "main": "./dist/index.js",
109
+ "types": "./dist/index.d.ts"
110
+ }