solve-engine 2.24.0 → 2.26.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.
- package/dist/{BytecodeBuilder-aqVa7Plx.d.cts → BytecodeBuilder-DSWKZi4f.d.cts} +11 -9
- package/dist/{BytecodeBuilder-aqVa7Plx.d.ts → BytecodeBuilder-DSWKZi4f.d.ts} +11 -9
- package/dist/CalendarBackend-MdS3Bb4P.d.cts +181 -0
- package/dist/CalendarBackend-MdS3Bb4P.d.ts +181 -0
- package/dist/{Configuration-DnzYPmoK.d.cts → Configuration-BxriK9Kw.d.cts} +63 -4
- package/dist/{Configuration-DnzYPmoK.d.ts → Configuration-BxriK9Kw.d.ts} +63 -4
- package/dist/DateCalendar-B85t6Vk6.d.ts +90 -0
- package/dist/DateCalendar-CUGI1fT4.d.cts +90 -0
- package/dist/{EngineError-D1kXsjIj.d.cts → EngineError-C-kBwYlN.d.cts} +33 -4
- package/dist/{EngineError-D1kXsjIj.d.ts → EngineError-C-kBwYlN.d.ts} +33 -4
- package/dist/{FormattingSettings-bRKjU7wI.d.ts → FormattingSettings-ByO-4wiM.d.cts} +14 -0
- package/dist/{FormattingSettings-bRKjU7wI.d.cts → FormattingSettings-CvCzAfsz.d.ts} +14 -0
- package/dist/{Lexer-CqagTewQ.d.ts → Lexer-DhGhoAa2.d.cts} +96 -37
- package/dist/{Lexer-CCHFDcgP.d.cts → Lexer-DqtnZMC5.d.ts} +96 -37
- package/dist/{PackageCompatibility-CeAPVHZr.d.cts → PackageCompatibility-CNiTtC6S.d.cts} +1 -1
- package/dist/{PackageCompatibility-Bq82y0ZN.d.ts → PackageCompatibility-fj_f7uqC.d.ts} +1 -1
- package/dist/{PackageRegistry-B9-7fJGH.d.cts → PackageRegistry-BHBCFswo.d.cts} +377 -15
- package/dist/{PackageRegistry-CDEgfhT_.d.ts → PackageRegistry-CNZUwWHJ.d.ts} +377 -15
- package/dist/{Parselet-4oH5OuRt.d.cts → Parselet-DF3864la.d.cts} +26 -4
- package/dist/{Parselet-BwDqKFfK.d.ts → Parselet-Dgymjxzd.d.ts} +26 -4
- package/dist/{Token-CbP_OutD.d.cts → Token-D8f7yaz1.d.cts} +17 -0
- package/dist/{Token-CbP_OutD.d.ts → Token-D8f7yaz1.d.ts} +17 -0
- package/dist/{TokenNormalizer-OTPS0Otq.d.ts → TokenNormalizer-IF7nPRMp.d.ts} +46 -27
- package/dist/{TokenNormalizer-MXaKLJ_m.d.cts → TokenNormalizer-Pe3_390t.d.cts} +46 -27
- package/dist/{ScopeManager-BQBhlDAu.d.ts → VMBuiltins-CZiZRKn-.d.ts} +92 -10
- package/dist/{ScopeManager-DrXB3Nvm.d.cts → VMBuiltins-kv4rr0y5.d.cts} +92 -10
- package/dist/{VMCheckpoints-C5jC92o3.d.ts → VMCheckpoints-DXze6ypg.d.ts} +3 -3
- package/dist/{VMCheckpoints-BK32PTl2.d.cts → VMCheckpoints-yun4ocSv.d.cts} +3 -3
- package/dist/{Value-Ds3Gy07C.d.cts → Value-BYHw-x7q.d.cts} +57 -1
- package/dist/{Value-Ds3Gy07C.d.ts → Value-BYHw-x7q.d.ts} +57 -1
- package/dist/{WorkerError-DaNWQFp1.d.cts → WorkerError-BLZyNq6M.d.cts} +1 -1
- package/dist/{WorkerError-CVQbs6_D.d.ts → WorkerError-CfBJYueR.d.ts} +1 -1
- package/dist/chunk-2SYYKQ4Q.cjs +2 -0
- package/dist/chunk-2SYYKQ4Q.cjs.map +1 -0
- package/dist/chunk-6EYKVQT3.cjs +2 -0
- package/dist/chunk-6EYKVQT3.cjs.map +1 -0
- package/dist/chunk-7RC6RBS6.cjs +2 -0
- package/dist/chunk-7RC6RBS6.cjs.map +1 -0
- package/dist/chunk-AZX4NTYN.cjs +3 -0
- package/dist/chunk-AZX4NTYN.cjs.map +1 -0
- package/dist/{chunk-PTQCHMYA.js → chunk-BCR53EIL.js} +2 -2
- package/dist/{chunk-PTQCHMYA.js.map → chunk-BCR53EIL.js.map} +1 -1
- package/dist/chunk-BLJ6E577.js +2 -0
- package/dist/chunk-BLJ6E577.js.map +1 -0
- package/dist/{chunk-CMZSK6FY.cjs → chunk-C5GEMKUY.cjs} +3 -3
- package/dist/{chunk-CMZSK6FY.cjs.map → chunk-C5GEMKUY.cjs.map} +1 -1
- package/dist/chunk-CL7DM2FX.js +2 -0
- package/dist/chunk-CL7DM2FX.js.map +1 -0
- package/dist/chunk-CQLCTKMX.cjs +2 -0
- package/dist/chunk-CQLCTKMX.cjs.map +1 -0
- package/dist/chunk-CQY23OF5.cjs +5 -0
- package/dist/chunk-CQY23OF5.cjs.map +1 -0
- package/dist/chunk-D4VBWPWN.js +2 -0
- package/dist/chunk-D4VBWPWN.js.map +1 -0
- package/dist/chunk-E4HAKNBQ.cjs +2 -0
- package/dist/chunk-E4HAKNBQ.cjs.map +1 -0
- package/dist/{chunk-GP4H5OIT.js → chunk-ESZNJQ2C.js} +3 -3
- package/dist/{chunk-GP4H5OIT.js.map → chunk-ESZNJQ2C.js.map} +1 -1
- package/dist/{chunk-IJMNVBIS.js → chunk-FAO6DQ74.js} +2 -2
- package/dist/chunk-FAO6DQ74.js.map +1 -0
- package/dist/{chunk-2VE4OW4A.cjs → chunk-FDKTESBC.cjs} +2 -2
- package/dist/{chunk-2VE4OW4A.cjs.map → chunk-FDKTESBC.cjs.map} +1 -1
- package/dist/{chunk-RN3ISTM3.cjs → chunk-G2V33LFM.cjs} +2 -2
- package/dist/{chunk-RN3ISTM3.cjs.map → chunk-G2V33LFM.cjs.map} +1 -1
- package/dist/chunk-GJZIJK2Q.cjs +2 -0
- package/dist/chunk-GJZIJK2Q.cjs.map +1 -0
- package/dist/chunk-GQM6ICDM.js +2 -0
- package/dist/chunk-GQM6ICDM.js.map +1 -0
- package/dist/chunk-GVL3ZMS7.cjs +2 -0
- package/dist/chunk-GVL3ZMS7.cjs.map +1 -0
- package/dist/chunk-GXO7TSXQ.cjs +3 -0
- package/dist/chunk-GXO7TSXQ.cjs.map +1 -0
- package/dist/{chunk-OMHRBKAT.js → chunk-HANGBVEE.js} +2 -2
- package/dist/{chunk-OMHRBKAT.js.map → chunk-HANGBVEE.js.map} +1 -1
- package/dist/chunk-J4K72CQN.js +2 -0
- package/dist/chunk-J4K72CQN.js.map +1 -0
- package/dist/chunk-LE6WZLJ4.js +2 -0
- package/dist/chunk-LE6WZLJ4.js.map +1 -0
- package/dist/chunk-LMZDTQS5.js +3 -0
- package/dist/chunk-LMZDTQS5.js.map +1 -0
- package/dist/chunk-LQIRBP4Q.js +2 -0
- package/dist/chunk-LQIRBP4Q.js.map +1 -0
- package/dist/{chunk-UXR7JIPX.js → chunk-LTUYWJGO.js} +2 -2
- package/dist/{chunk-UXR7JIPX.js.map → chunk-LTUYWJGO.js.map} +1 -1
- package/dist/chunk-MCU7UYKG.js +3 -0
- package/dist/{chunk-7EP36NXE.js.map → chunk-MCU7UYKG.js.map} +1 -1
- package/dist/chunk-MTN53APQ.js +5 -0
- package/dist/chunk-MTN53APQ.js.map +1 -0
- package/dist/chunk-OPKJ2WWB.cjs +3 -0
- package/dist/chunk-OPKJ2WWB.cjs.map +1 -0
- package/dist/chunk-QQHHZPEW.cjs +2 -0
- package/dist/chunk-QQHHZPEW.cjs.map +1 -0
- package/dist/chunk-RRUGQ6DM.js +2 -0
- package/dist/chunk-RRUGQ6DM.js.map +1 -0
- package/dist/chunk-S3ODNMJS.js +2 -0
- package/dist/chunk-S3ODNMJS.js.map +1 -0
- package/dist/{chunk-CDNJZBM3.cjs → chunk-SE6ZCGZ5.cjs} +2 -2
- package/dist/{chunk-CDNJZBM3.cjs.map → chunk-SE6ZCGZ5.cjs.map} +1 -1
- package/dist/chunk-TC23XEAV.js +2 -0
- package/dist/chunk-TC23XEAV.js.map +1 -0
- package/dist/{chunk-MWWAKZOD.cjs → chunk-TMQ37JQY.cjs} +3 -3
- package/dist/{chunk-MWWAKZOD.cjs.map → chunk-TMQ37JQY.cjs.map} +1 -1
- package/dist/chunk-TPPM4QSS.cjs +2 -0
- package/dist/chunk-TPPM4QSS.cjs.map +1 -0
- package/dist/chunk-VB6QMU2W.js +3 -0
- package/dist/chunk-VB6QMU2W.js.map +1 -0
- package/dist/chunk-VQO54ZMA.js +2 -0
- package/dist/chunk-VQO54ZMA.js.map +1 -0
- package/dist/chunk-Y7XRA2EV.js +2 -0
- package/dist/chunk-Y7XRA2EV.js.map +1 -0
- package/dist/{chunk-5IJD5L3O.cjs → chunk-YBQOQTVL.cjs} +2 -2
- package/dist/chunk-YBQOQTVL.cjs.map +1 -0
- package/dist/chunk-YG7UWQFV.js +2 -0
- package/dist/chunk-YG7UWQFV.js.map +1 -0
- package/dist/chunk-YS2OW75C.cjs +2 -0
- package/dist/chunk-YS2OW75C.cjs.map +1 -0
- package/dist/chunk-ZC2NPRLO.js +3 -0
- package/dist/chunk-ZC2NPRLO.js.map +1 -0
- package/dist/chunk-ZDJTDFTR.cjs +2 -0
- package/dist/chunk-ZDJTDFTR.cjs.map +1 -0
- package/dist/chunk-ZE5KKMBV.cjs +2 -0
- package/dist/chunk-ZE5KKMBV.cjs.map +1 -0
- package/dist/chunk-ZSLVLMO5.cjs +2 -0
- package/dist/chunk-ZSLVLMO5.cjs.map +1 -0
- package/dist/constants.cjs +1 -1
- package/dist/constants.d.cts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/engine.cjs +1 -1
- package/dist/engine.d.cts +15 -13
- package/dist/engine.d.ts +15 -13
- package/dist/engine.js +1 -1
- package/dist/errors.cjs +1 -1
- package/dist/errors.d.cts +3 -3
- package/dist/errors.d.ts +3 -3
- package/dist/errors.js +1 -1
- package/dist/format.cjs +1 -1
- package/dist/format.d.cts +4 -3
- package/dist/format.d.ts +4 -3
- package/dist/format.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -14
- package/dist/index.d.ts +16 -14
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/language.d.cts +13 -12
- package/dist/language.d.ts +13 -12
- package/dist/lexer.cjs +1 -1
- package/dist/lexer.cjs.map +1 -1
- package/dist/lexer.d.cts +9 -8
- package/dist/lexer.d.ts +9 -8
- package/dist/lexer.js +1 -1
- package/dist/lexer.js.map +1 -1
- package/dist/normalizer.cjs +1 -1
- package/dist/normalizer.d.cts +3 -3
- package/dist/normalizer.d.ts +3 -3
- package/dist/normalizer.js +1 -1
- package/dist/packages.cjs +1 -1
- package/dist/packages.d.cts +12 -11
- package/dist/packages.d.ts +12 -11
- package/dist/packages.js +1 -1
- package/dist/parser.cjs +1 -1
- package/dist/parser.d.cts +6 -5
- package/dist/parser.d.ts +6 -5
- package/dist/parser.js +1 -1
- package/dist/{pipeline-69q2tsLE.d.cts → pipeline-BYkKNpql.d.cts} +1 -1
- package/dist/{pipeline-DTqGLPsV.d.ts → pipeline-Cl7KW8CB.d.ts} +1 -1
- package/dist/resolvers.d.cts +3 -3
- package/dist/resolvers.d.ts +3 -3
- package/dist/temporal.cjs +2 -0
- package/dist/temporal.cjs.map +1 -0
- package/dist/temporal.d.cts +201 -0
- package/dist/temporal.d.ts +201 -0
- package/dist/temporal.js +2 -0
- package/dist/temporal.js.map +1 -0
- package/dist/testing.cjs +2 -2
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +13 -12
- package/dist/testing.d.ts +13 -12
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/uom.cjs +1 -1
- package/dist/uom.d.cts +3 -3
- package/dist/uom.d.ts +3 -3
- package/dist/uom.js +1 -1
- package/dist/vm.cjs +1 -1
- package/dist/vm.cjs.map +1 -1
- package/dist/vm.d.cts +9 -57
- package/dist/vm.d.ts +9 -57
- package/dist/vm.js +1 -1
- package/dist/vm.js.map +1 -1
- package/dist/worker.cjs +2 -2
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +36 -14
- package/dist/worker.d.ts +36 -14
- package/dist/worker.js +2 -2
- package/dist/worker.js.map +1 -1
- package/package.json +16 -5
- package/dist/chunk-2BXNZM3G.js +0 -2
- package/dist/chunk-2BXNZM3G.js.map +0 -1
- package/dist/chunk-2JSNWYYA.cjs +0 -3
- package/dist/chunk-2JSNWYYA.cjs.map +0 -1
- package/dist/chunk-3SHWTGTP.js +0 -2
- package/dist/chunk-3SHWTGTP.js.map +0 -1
- package/dist/chunk-5GL4SAVH.cjs +0 -2
- package/dist/chunk-5GL4SAVH.cjs.map +0 -1
- package/dist/chunk-5IJD5L3O.cjs.map +0 -1
- package/dist/chunk-72N3ZRVE.cjs +0 -2
- package/dist/chunk-72N3ZRVE.cjs.map +0 -1
- package/dist/chunk-7EP36NXE.js +0 -3
- package/dist/chunk-A4JV7HRB.js +0 -3
- package/dist/chunk-A4JV7HRB.js.map +0 -1
- package/dist/chunk-AUOE7MFI.cjs +0 -2
- package/dist/chunk-AUOE7MFI.cjs.map +0 -1
- package/dist/chunk-BDF4VCQX.js +0 -3
- package/dist/chunk-BDF4VCQX.js.map +0 -1
- package/dist/chunk-D2Q2VFJ6.js +0 -2
- package/dist/chunk-D2Q2VFJ6.js.map +0 -1
- package/dist/chunk-DA7M6H63.cjs +0 -2
- package/dist/chunk-DA7M6H63.cjs.map +0 -1
- package/dist/chunk-ELQQKZN3.cjs +0 -3
- package/dist/chunk-ELQQKZN3.cjs.map +0 -1
- package/dist/chunk-F7QIBC4B.cjs +0 -3
- package/dist/chunk-F7QIBC4B.cjs.map +0 -1
- package/dist/chunk-HQ7BKXG7.js +0 -2
- package/dist/chunk-HQ7BKXG7.js.map +0 -1
- package/dist/chunk-IHAZL4EF.cjs +0 -2
- package/dist/chunk-IHAZL4EF.cjs.map +0 -1
- package/dist/chunk-IJMNVBIS.js.map +0 -1
- package/dist/chunk-IPSOWFCA.js +0 -2
- package/dist/chunk-IPSOWFCA.js.map +0 -1
- package/dist/chunk-LM6ZQUEU.js +0 -2
- package/dist/chunk-LM6ZQUEU.js.map +0 -1
- package/dist/chunk-LTJV3VJE.cjs +0 -2
- package/dist/chunk-LTJV3VJE.cjs.map +0 -1
- package/dist/chunk-NUF66H57.js +0 -5
- package/dist/chunk-NUF66H57.js.map +0 -1
- package/dist/chunk-PWWQZFAE.js +0 -2
- package/dist/chunk-PWWQZFAE.js.map +0 -1
- package/dist/chunk-RE6AIU6Y.js +0 -3
- package/dist/chunk-RE6AIU6Y.js.map +0 -1
- package/dist/chunk-RECRD45C.cjs +0 -5
- package/dist/chunk-RECRD45C.cjs.map +0 -1
- package/dist/chunk-RENO2AWO.js +0 -2
- package/dist/chunk-RENO2AWO.js.map +0 -1
- package/dist/chunk-RMCN5WFO.cjs +0 -2
- package/dist/chunk-RMCN5WFO.cjs.map +0 -1
- package/dist/chunk-S46R5QZP.cjs +0 -2
- package/dist/chunk-S46R5QZP.cjs.map +0 -1
- package/dist/chunk-UPH22K2T.cjs +0 -2
- package/dist/chunk-UPH22K2T.cjs.map +0 -1
- package/dist/chunk-UY3ID6JF.cjs +0 -2
- package/dist/chunk-UY3ID6JF.cjs.map +0 -1
- package/dist/chunk-WFOQRPA6.js +0 -2
- package/dist/chunk-WFOQRPA6.js.map +0 -1
- package/dist/chunk-XFJABR3B.js +0 -2
- package/dist/chunk-XFJABR3B.js.map +0 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { C as CalendarBackend, a as CalendarFields, Z as ZonedFields } from './CalendarBackend-MdS3Bb4P.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The default {@link CalendarBackend}: the JavaScript `Date` object, read in
|
|
5
|
+
* the host process's time zone, with `Intl.DateTimeFormat` for named zones.
|
|
6
|
+
*
|
|
7
|
+
* This is the calendar code the engine has always run, moved behind the
|
|
8
|
+
* interface method by method rather than rewritten, so a host that configures
|
|
9
|
+
* nothing sees the same instants and the same strings it did before the
|
|
10
|
+
* backend existed. Where `Date` has a quirk (a two-digit year in a
|
|
11
|
+
* constructor maps to the 1900s, an out-of-range instant answers `NaN`), the
|
|
12
|
+
* quirk is kept here deliberately: the point of this backend is to be the
|
|
13
|
+
* behaviour the `Temporal` backend is measured against, not to improve on it.
|
|
14
|
+
*
|
|
15
|
+
* It stays the default because it is the one calendar every supported runtime
|
|
16
|
+
* has. `Temporal` ships unflagged in Node 26 and in current Chrome, Firefox
|
|
17
|
+
* and Deno, but not in Safari or in the Node 22 and 24 the engine supports,
|
|
18
|
+
* and the smallest polyfill adds about twenty kilobytes gzipped to a bundle
|
|
19
|
+
* that a host doing plain arithmetic never needs. A host that wants
|
|
20
|
+
* `Temporal` opts in through the engine's `calendar` option with the backend
|
|
21
|
+
* from `solve-engine/temporal`, and pays for it only then.
|
|
22
|
+
*/
|
|
23
|
+
declare class DateCalendar implements CalendarBackend {
|
|
24
|
+
now(): number;
|
|
25
|
+
fields(epochMs: number): CalendarFields;
|
|
26
|
+
localMidnight(year: number, month0: number, day: number): number;
|
|
27
|
+
localWallClock(year: number, month0: number, day: number, minutesPastMidnight: number): number;
|
|
28
|
+
addDays(epochMs: number, days: number): number;
|
|
29
|
+
addMonths(epochMs: number, months: number): number;
|
|
30
|
+
utcOffsetMinutes(epochMs: number): number;
|
|
31
|
+
parseIso8601(text: string): number;
|
|
32
|
+
formatLongDate(epochMs: number, locale: string): string;
|
|
33
|
+
formatTimeOfDay(epochMs: number, locale: string): string;
|
|
34
|
+
zoneOffsetMinutes(zone: string, epochMs: number): number;
|
|
35
|
+
fieldsInZone(zone: string, epochMs: number): ZonedFields;
|
|
36
|
+
formatTimeInZone(zone: string, epochMs: number): string;
|
|
37
|
+
formatDateInZone(zone: string, epochMs: number): string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The one `Date` backend, shared by every engine that configures no other.
|
|
41
|
+
*
|
|
42
|
+
* Stateless, so sharing is safe: it holds no zone of its own and reads the
|
|
43
|
+
* process's. It is also what the sites with no engine in hand use (the
|
|
44
|
+
* normaliser rules that fuse a literal, `days in <period>`, the stocks and
|
|
45
|
+
* historical-currency date phrases, and `formatValue`), which is why an
|
|
46
|
+
* engine's own backend is the default here rather than a second copy.
|
|
47
|
+
*/
|
|
48
|
+
declare const DATE_CALENDAR: CalendarBackend;
|
|
49
|
+
/**
|
|
50
|
+
* The backend a plugin function or converter should compute with: the one
|
|
51
|
+
* on its execution context, or the `Date` backend when the handler was
|
|
52
|
+
* called with no context (a direct call from a test, or an `as` converter
|
|
53
|
+
* invoked outside the VM).
|
|
54
|
+
*
|
|
55
|
+
* @param context - The execution context the handler received, if any.
|
|
56
|
+
* @returns The engine's backend when the context carries one, else {@link DATE_CALENDAR}.
|
|
57
|
+
*/
|
|
58
|
+
declare function calendarOf(context?: {
|
|
59
|
+
readonly calendar?: CalendarBackend;
|
|
60
|
+
}): CalendarBackend;
|
|
61
|
+
/**
|
|
62
|
+
* A `Date` backend that computes in a named time zone rather than the host
|
|
63
|
+
* process's.
|
|
64
|
+
*
|
|
65
|
+
* This is how a host pins the zone the engine reads dates in, and it is the
|
|
66
|
+
* only knob for it: the zone belongs to the calendar backend, which already
|
|
67
|
+
* owns what "local" means, so there is deliberately no `date.zone` config
|
|
68
|
+
* field to drift against it.
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* import { createEngine, dateCalendarInZone } from "solve-engine";
|
|
72
|
+
* const engine = createEngine({ calendar: dateCalendarInZone("Asia/Tokyo") });
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* It ships on the `Date` backend on purpose. `Temporal` is undefined on Node
|
|
76
|
+
* 24 and in Safari, so "pass a `Temporal` backend" would put the zone out of
|
|
77
|
+
* reach for most hosts today; `Temporal` stays an accuracy upgrade for the
|
|
78
|
+
* ambiguous wall clocks around a daylight-saving transition, never a
|
|
79
|
+
* prerequisite for naming a zone at all.
|
|
80
|
+
*
|
|
81
|
+
* @param zone - An IANA zone name, e.g. `"Asia/Tokyo"`.
|
|
82
|
+
* @returns A backend whose local zone is that one.
|
|
83
|
+
* @throws A `DATE_ZONE_UNKNOWN` config error when this runtime's `Intl` does
|
|
84
|
+
* not know the zone. Refused here rather than per line, because a backend
|
|
85
|
+
* that cannot compute in the zone it was asked for must not quietly answer
|
|
86
|
+
* in another one.
|
|
87
|
+
*/
|
|
88
|
+
declare function dateCalendarInZone(zone: string): CalendarBackend;
|
|
89
|
+
|
|
90
|
+
export { DATE_CALENDAR as D, DateCalendar as a, calendarOf as c, dateCalendarInZone as d };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { C as CalendarBackend, a as CalendarFields, Z as ZonedFields } from './CalendarBackend-MdS3Bb4P.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The default {@link CalendarBackend}: the JavaScript `Date` object, read in
|
|
5
|
+
* the host process's time zone, with `Intl.DateTimeFormat` for named zones.
|
|
6
|
+
*
|
|
7
|
+
* This is the calendar code the engine has always run, moved behind the
|
|
8
|
+
* interface method by method rather than rewritten, so a host that configures
|
|
9
|
+
* nothing sees the same instants and the same strings it did before the
|
|
10
|
+
* backend existed. Where `Date` has a quirk (a two-digit year in a
|
|
11
|
+
* constructor maps to the 1900s, an out-of-range instant answers `NaN`), the
|
|
12
|
+
* quirk is kept here deliberately: the point of this backend is to be the
|
|
13
|
+
* behaviour the `Temporal` backend is measured against, not to improve on it.
|
|
14
|
+
*
|
|
15
|
+
* It stays the default because it is the one calendar every supported runtime
|
|
16
|
+
* has. `Temporal` ships unflagged in Node 26 and in current Chrome, Firefox
|
|
17
|
+
* and Deno, but not in Safari or in the Node 22 and 24 the engine supports,
|
|
18
|
+
* and the smallest polyfill adds about twenty kilobytes gzipped to a bundle
|
|
19
|
+
* that a host doing plain arithmetic never needs. A host that wants
|
|
20
|
+
* `Temporal` opts in through the engine's `calendar` option with the backend
|
|
21
|
+
* from `solve-engine/temporal`, and pays for it only then.
|
|
22
|
+
*/
|
|
23
|
+
declare class DateCalendar implements CalendarBackend {
|
|
24
|
+
now(): number;
|
|
25
|
+
fields(epochMs: number): CalendarFields;
|
|
26
|
+
localMidnight(year: number, month0: number, day: number): number;
|
|
27
|
+
localWallClock(year: number, month0: number, day: number, minutesPastMidnight: number): number;
|
|
28
|
+
addDays(epochMs: number, days: number): number;
|
|
29
|
+
addMonths(epochMs: number, months: number): number;
|
|
30
|
+
utcOffsetMinutes(epochMs: number): number;
|
|
31
|
+
parseIso8601(text: string): number;
|
|
32
|
+
formatLongDate(epochMs: number, locale: string): string;
|
|
33
|
+
formatTimeOfDay(epochMs: number, locale: string): string;
|
|
34
|
+
zoneOffsetMinutes(zone: string, epochMs: number): number;
|
|
35
|
+
fieldsInZone(zone: string, epochMs: number): ZonedFields;
|
|
36
|
+
formatTimeInZone(zone: string, epochMs: number): string;
|
|
37
|
+
formatDateInZone(zone: string, epochMs: number): string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The one `Date` backend, shared by every engine that configures no other.
|
|
41
|
+
*
|
|
42
|
+
* Stateless, so sharing is safe: it holds no zone of its own and reads the
|
|
43
|
+
* process's. It is also what the sites with no engine in hand use (the
|
|
44
|
+
* normaliser rules that fuse a literal, `days in <period>`, the stocks and
|
|
45
|
+
* historical-currency date phrases, and `formatValue`), which is why an
|
|
46
|
+
* engine's own backend is the default here rather than a second copy.
|
|
47
|
+
*/
|
|
48
|
+
declare const DATE_CALENDAR: CalendarBackend;
|
|
49
|
+
/**
|
|
50
|
+
* The backend a plugin function or converter should compute with: the one
|
|
51
|
+
* on its execution context, or the `Date` backend when the handler was
|
|
52
|
+
* called with no context (a direct call from a test, or an `as` converter
|
|
53
|
+
* invoked outside the VM).
|
|
54
|
+
*
|
|
55
|
+
* @param context - The execution context the handler received, if any.
|
|
56
|
+
* @returns The engine's backend when the context carries one, else {@link DATE_CALENDAR}.
|
|
57
|
+
*/
|
|
58
|
+
declare function calendarOf(context?: {
|
|
59
|
+
readonly calendar?: CalendarBackend;
|
|
60
|
+
}): CalendarBackend;
|
|
61
|
+
/**
|
|
62
|
+
* A `Date` backend that computes in a named time zone rather than the host
|
|
63
|
+
* process's.
|
|
64
|
+
*
|
|
65
|
+
* This is how a host pins the zone the engine reads dates in, and it is the
|
|
66
|
+
* only knob for it: the zone belongs to the calendar backend, which already
|
|
67
|
+
* owns what "local" means, so there is deliberately no `date.zone` config
|
|
68
|
+
* field to drift against it.
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* import { createEngine, dateCalendarInZone } from "solve-engine";
|
|
72
|
+
* const engine = createEngine({ calendar: dateCalendarInZone("Asia/Tokyo") });
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* It ships on the `Date` backend on purpose. `Temporal` is undefined on Node
|
|
76
|
+
* 24 and in Safari, so "pass a `Temporal` backend" would put the zone out of
|
|
77
|
+
* reach for most hosts today; `Temporal` stays an accuracy upgrade for the
|
|
78
|
+
* ambiguous wall clocks around a daylight-saving transition, never a
|
|
79
|
+
* prerequisite for naming a zone at all.
|
|
80
|
+
*
|
|
81
|
+
* @param zone - An IANA zone name, e.g. `"Asia/Tokyo"`.
|
|
82
|
+
* @returns A backend whose local zone is that one.
|
|
83
|
+
* @throws A `DATE_ZONE_UNKNOWN` config error when this runtime's `Intl` does
|
|
84
|
+
* not know the zone. Refused here rather than per line, because a backend
|
|
85
|
+
* that cannot compute in the zone it was asked for must not quietly answer
|
|
86
|
+
* in another one.
|
|
87
|
+
*/
|
|
88
|
+
declare function dateCalendarInZone(zone: string): CalendarBackend;
|
|
89
|
+
|
|
90
|
+
export { DATE_CALENDAR as D, DateCalendar as a, calendarOf as c, dateCalendarInZone as d };
|
|
@@ -38,6 +38,8 @@ declare const CoreErrorCodes: {
|
|
|
38
38
|
readonly UNEXPECTED_TRAILING_TOKEN: "UNEXPECTED_TRAILING_TOKEN";
|
|
39
39
|
readonly PARSE_ERROR: "PARSE_ERROR";
|
|
40
40
|
readonly TOO_MANY_NUMERIC_CONSTANTS: "TOO_MANY_NUMERIC_CONSTANTS";
|
|
41
|
+
/** A raw bytecode operand outside 0 to 255, or a jump patch outside the emitted stream (`parser/BytecodeBuilder.ts`'s `emitIndex`, `emitByte`, `patchJump`). `build()` keeps one byte per operand, so 300 used to become 44 with no error and the program read the wrong constant or plugin function. A package-authoring fault, reported at compile time. */
|
|
42
|
+
readonly BYTECODE_OPERAND_OUT_OF_RANGE: "BYTECODE_OPERAND_OUT_OF_RANGE";
|
|
41
43
|
readonly TOO_MANY_STRING_CONSTANTS: "TOO_MANY_STRING_CONSTANTS";
|
|
42
44
|
readonly NO_MATCHING_PHRASE_ALTERNATIVE: "NO_MATCHING_PHRASE_ALTERNATIVE";
|
|
43
45
|
readonly INVALID_PHRASE_PATTERN: "INVALID_PHRASE_PATTERN";
|
|
@@ -168,6 +170,10 @@ declare const CoreErrorCodes: {
|
|
|
168
170
|
readonly INVALID_TIME_LITERAL: "INVALID_TIME_LITERAL";
|
|
169
171
|
/** A live-data form evaluated on an engine whose host switched the network off (`network.enabled: false`, see `constants/Configuration.ts`'s `NetworkConfig`). A recoverable Error value, raised by the VM for a currency conversion with no primed rate and for a plugin function that returned a promise, and by `createQueryResolver`'s plugin function when its preflight was skipped. Names the setting, so the reader knows it is policy rather than an outage. */
|
|
170
172
|
readonly NETWORK_DISABLED: "NETWORK_DISABLED";
|
|
173
|
+
/** `createTemporalCalendar()` was handed something that is not a usable `Temporal` implementation: no `Now.instant`, `Now.timeZoneId`, `Instant.fromEpochMilliseconds` or `PlainDateTime.from`. Raised at construction, naming the missing member, rather than letting the first date computation fail on it obscurely. */
|
|
174
|
+
readonly TEMPORAL_IMPLEMENTATION_INVALID: "TEMPORAL_IMPLEMENTATION_INVALID";
|
|
175
|
+
/** The `timeZone` given to `createTemporalCalendar()` is not one the `Temporal` implementation knows. Raised at construction, so a misspelt zone is a configuration error the host sees once, not a `RangeError` from inside every date the engine computes. */
|
|
176
|
+
readonly TEMPORAL_TIME_ZONE_UNKNOWN: "TEMPORAL_TIME_ZONE_UNKNOWN";
|
|
171
177
|
/** `fromJSON()` handed an object that is not a snapshot at all, or whose serialised-shape version does not match this engine's reader. The versioning gate that refuses an incompatible snapshot clearly rather than restoring it wrongly. See `engine/EngineSnapshot.ts`'s `assertRestorable()`. */
|
|
172
178
|
readonly SNAPSHOT_VERSION_MISMATCH: "SNAPSHOT_VERSION_MISMATCH";
|
|
173
179
|
/** A snapshot with the right envelope but internally inconsistent contents (an unrecognised number sentinel, an unknown value tag). Distinct from a version mismatch: the format is right, the payload is not. */
|
|
@@ -178,6 +184,8 @@ declare const CoreErrorCodes: {
|
|
|
178
184
|
readonly INVALID_CONFIG_PATH: "INVALID_CONFIG_PATH";
|
|
179
185
|
readonly CONFIG_SECTION_NOT_FOUND: "CONFIG_SECTION_NOT_FOUND";
|
|
180
186
|
readonly CONFIG_PROPERTY_NOT_FOUND: "CONFIG_PROPERTY_NOT_FOUND";
|
|
187
|
+
/** `calendar: "temporal"` was asked for on a runtime with no `Temporal`. Refused rather than silently computing on `Date`, because a host that named Temporal did so to be sure what it was computing on. Recoverable. */
|
|
188
|
+
readonly CALENDAR_TEMPORAL_UNAVAILABLE: "CALENDAR_TEMPORAL_UNAVAILABLE";
|
|
181
189
|
readonly PLUGIN_OPERATOR_COLLISION: "PLUGIN_OPERATOR_COLLISION";
|
|
182
190
|
readonly PLUGIN_KEYWORD_COLLISION: "PLUGIN_KEYWORD_COLLISION";
|
|
183
191
|
readonly PLUGIN_UNIT_COLLISION: "PLUGIN_UNIT_COLLISION";
|
|
@@ -199,11 +207,32 @@ declare const CoreErrorCodes: {
|
|
|
199
207
|
/** Every error code the engine's own layers can produce, from {@link CoreErrorCodes}. */
|
|
200
208
|
type CoreErrorCode = (typeof CoreErrorCodes)[keyof typeof CoreErrorCodes];
|
|
201
209
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
210
|
+
* Codes for the datetime forms whose failure is raised OUTSIDE the datetime
|
|
211
|
+
* package.
|
|
212
|
+
*
|
|
213
|
+
* These sit here rather than beside the datetime parselets, which is where a
|
|
214
|
+
* package's own code object belongs, because the two sites that raise them are
|
|
215
|
+
* `vm/VM.ts` (the `in <zone>` branch of the unit-conversion opcode) and
|
|
216
|
+
* `calendar/DateCalendar.ts` (the zone-bound backend factory), and neither may
|
|
217
|
+
* import from `packages/`. A code object in the datetime package would put the
|
|
218
|
+
* name a core file needs on the wrong side of that line.
|
|
219
|
+
*/
|
|
220
|
+
declare const DatetimeErrorCodes: {
|
|
221
|
+
/** `2026-04-03 in Atlantis`: a Datetime met `in <name>` and the name is neither a zone this engine knows nor a unit. Before this code the epoch-millisecond payload was simply labelled with the name, and the line answered a fourteen-digit quantity in a unit called Atlantis. */
|
|
222
|
+
readonly DATETIME_ZONE_UNKNOWN: "DATETIME_ZONE_UNKNOWN";
|
|
223
|
+
/** `2026-04-03 in furlongs`: the same handler, where the name IS a real unit. Separate from `DATETIME_ZONE_UNKNOWN` because the two mistakes have different fixes: one is a misspelt zone, the other is a category error, and a message that suggests checking the spelling of `furlongs` would be no help at all. */
|
|
224
|
+
readonly DATETIME_NOT_CONVERTIBLE: "DATETIME_NOT_CONVERTIBLE";
|
|
225
|
+
/** `dateCalendarInZone("Europe/Atlantis")`: the zone-bound `Date` backend factory, given a zone this runtime's `Intl` cannot format with. Raised at construction rather than per line, because a backend that cannot compute in the zone it was asked for must not silently answer in another one. */
|
|
226
|
+
readonly DATE_ZONE_UNKNOWN: "DATE_ZONE_UNKNOWN";
|
|
227
|
+
};
|
|
228
|
+
/** Every code from {@link DatetimeErrorCodes}. */
|
|
229
|
+
type DatetimeErrorCode = (typeof DatetimeErrorCodes)[keyof typeof DatetimeErrorCodes];
|
|
230
|
+
/**
|
|
231
|
+
* The aggregated catalog type. Currently `CoreErrorCode` and
|
|
232
|
+
* `DatetimeErrorCode`, union in each package's own code-object type here as
|
|
233
|
+
* Phase 5 converts it, e.g. `CoreErrorCode | WeatherErrorCode | ...`.
|
|
205
234
|
*/
|
|
206
|
-
type ErrorCode = CoreErrorCode;
|
|
235
|
+
type ErrorCode = CoreErrorCode | DatetimeErrorCode;
|
|
207
236
|
|
|
208
237
|
/**
|
|
209
238
|
* The engine's structured error type, the "Rust/Go-style, verbose, easy to
|
|
@@ -38,6 +38,8 @@ declare const CoreErrorCodes: {
|
|
|
38
38
|
readonly UNEXPECTED_TRAILING_TOKEN: "UNEXPECTED_TRAILING_TOKEN";
|
|
39
39
|
readonly PARSE_ERROR: "PARSE_ERROR";
|
|
40
40
|
readonly TOO_MANY_NUMERIC_CONSTANTS: "TOO_MANY_NUMERIC_CONSTANTS";
|
|
41
|
+
/** A raw bytecode operand outside 0 to 255, or a jump patch outside the emitted stream (`parser/BytecodeBuilder.ts`'s `emitIndex`, `emitByte`, `patchJump`). `build()` keeps one byte per operand, so 300 used to become 44 with no error and the program read the wrong constant or plugin function. A package-authoring fault, reported at compile time. */
|
|
42
|
+
readonly BYTECODE_OPERAND_OUT_OF_RANGE: "BYTECODE_OPERAND_OUT_OF_RANGE";
|
|
41
43
|
readonly TOO_MANY_STRING_CONSTANTS: "TOO_MANY_STRING_CONSTANTS";
|
|
42
44
|
readonly NO_MATCHING_PHRASE_ALTERNATIVE: "NO_MATCHING_PHRASE_ALTERNATIVE";
|
|
43
45
|
readonly INVALID_PHRASE_PATTERN: "INVALID_PHRASE_PATTERN";
|
|
@@ -168,6 +170,10 @@ declare const CoreErrorCodes: {
|
|
|
168
170
|
readonly INVALID_TIME_LITERAL: "INVALID_TIME_LITERAL";
|
|
169
171
|
/** A live-data form evaluated on an engine whose host switched the network off (`network.enabled: false`, see `constants/Configuration.ts`'s `NetworkConfig`). A recoverable Error value, raised by the VM for a currency conversion with no primed rate and for a plugin function that returned a promise, and by `createQueryResolver`'s plugin function when its preflight was skipped. Names the setting, so the reader knows it is policy rather than an outage. */
|
|
170
172
|
readonly NETWORK_DISABLED: "NETWORK_DISABLED";
|
|
173
|
+
/** `createTemporalCalendar()` was handed something that is not a usable `Temporal` implementation: no `Now.instant`, `Now.timeZoneId`, `Instant.fromEpochMilliseconds` or `PlainDateTime.from`. Raised at construction, naming the missing member, rather than letting the first date computation fail on it obscurely. */
|
|
174
|
+
readonly TEMPORAL_IMPLEMENTATION_INVALID: "TEMPORAL_IMPLEMENTATION_INVALID";
|
|
175
|
+
/** The `timeZone` given to `createTemporalCalendar()` is not one the `Temporal` implementation knows. Raised at construction, so a misspelt zone is a configuration error the host sees once, not a `RangeError` from inside every date the engine computes. */
|
|
176
|
+
readonly TEMPORAL_TIME_ZONE_UNKNOWN: "TEMPORAL_TIME_ZONE_UNKNOWN";
|
|
171
177
|
/** `fromJSON()` handed an object that is not a snapshot at all, or whose serialised-shape version does not match this engine's reader. The versioning gate that refuses an incompatible snapshot clearly rather than restoring it wrongly. See `engine/EngineSnapshot.ts`'s `assertRestorable()`. */
|
|
172
178
|
readonly SNAPSHOT_VERSION_MISMATCH: "SNAPSHOT_VERSION_MISMATCH";
|
|
173
179
|
/** A snapshot with the right envelope but internally inconsistent contents (an unrecognised number sentinel, an unknown value tag). Distinct from a version mismatch: the format is right, the payload is not. */
|
|
@@ -178,6 +184,8 @@ declare const CoreErrorCodes: {
|
|
|
178
184
|
readonly INVALID_CONFIG_PATH: "INVALID_CONFIG_PATH";
|
|
179
185
|
readonly CONFIG_SECTION_NOT_FOUND: "CONFIG_SECTION_NOT_FOUND";
|
|
180
186
|
readonly CONFIG_PROPERTY_NOT_FOUND: "CONFIG_PROPERTY_NOT_FOUND";
|
|
187
|
+
/** `calendar: "temporal"` was asked for on a runtime with no `Temporal`. Refused rather than silently computing on `Date`, because a host that named Temporal did so to be sure what it was computing on. Recoverable. */
|
|
188
|
+
readonly CALENDAR_TEMPORAL_UNAVAILABLE: "CALENDAR_TEMPORAL_UNAVAILABLE";
|
|
181
189
|
readonly PLUGIN_OPERATOR_COLLISION: "PLUGIN_OPERATOR_COLLISION";
|
|
182
190
|
readonly PLUGIN_KEYWORD_COLLISION: "PLUGIN_KEYWORD_COLLISION";
|
|
183
191
|
readonly PLUGIN_UNIT_COLLISION: "PLUGIN_UNIT_COLLISION";
|
|
@@ -199,11 +207,32 @@ declare const CoreErrorCodes: {
|
|
|
199
207
|
/** Every error code the engine's own layers can produce, from {@link CoreErrorCodes}. */
|
|
200
208
|
type CoreErrorCode = (typeof CoreErrorCodes)[keyof typeof CoreErrorCodes];
|
|
201
209
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
210
|
+
* Codes for the datetime forms whose failure is raised OUTSIDE the datetime
|
|
211
|
+
* package.
|
|
212
|
+
*
|
|
213
|
+
* These sit here rather than beside the datetime parselets, which is where a
|
|
214
|
+
* package's own code object belongs, because the two sites that raise them are
|
|
215
|
+
* `vm/VM.ts` (the `in <zone>` branch of the unit-conversion opcode) and
|
|
216
|
+
* `calendar/DateCalendar.ts` (the zone-bound backend factory), and neither may
|
|
217
|
+
* import from `packages/`. A code object in the datetime package would put the
|
|
218
|
+
* name a core file needs on the wrong side of that line.
|
|
219
|
+
*/
|
|
220
|
+
declare const DatetimeErrorCodes: {
|
|
221
|
+
/** `2026-04-03 in Atlantis`: a Datetime met `in <name>` and the name is neither a zone this engine knows nor a unit. Before this code the epoch-millisecond payload was simply labelled with the name, and the line answered a fourteen-digit quantity in a unit called Atlantis. */
|
|
222
|
+
readonly DATETIME_ZONE_UNKNOWN: "DATETIME_ZONE_UNKNOWN";
|
|
223
|
+
/** `2026-04-03 in furlongs`: the same handler, where the name IS a real unit. Separate from `DATETIME_ZONE_UNKNOWN` because the two mistakes have different fixes: one is a misspelt zone, the other is a category error, and a message that suggests checking the spelling of `furlongs` would be no help at all. */
|
|
224
|
+
readonly DATETIME_NOT_CONVERTIBLE: "DATETIME_NOT_CONVERTIBLE";
|
|
225
|
+
/** `dateCalendarInZone("Europe/Atlantis")`: the zone-bound `Date` backend factory, given a zone this runtime's `Intl` cannot format with. Raised at construction rather than per line, because a backend that cannot compute in the zone it was asked for must not silently answer in another one. */
|
|
226
|
+
readonly DATE_ZONE_UNKNOWN: "DATE_ZONE_UNKNOWN";
|
|
227
|
+
};
|
|
228
|
+
/** Every code from {@link DatetimeErrorCodes}. */
|
|
229
|
+
type DatetimeErrorCode = (typeof DatetimeErrorCodes)[keyof typeof DatetimeErrorCodes];
|
|
230
|
+
/**
|
|
231
|
+
* The aggregated catalog type. Currently `CoreErrorCode` and
|
|
232
|
+
* `DatetimeErrorCode`, union in each package's own code-object type here as
|
|
233
|
+
* Phase 5 converts it, e.g. `CoreErrorCode | WeatherErrorCode | ...`.
|
|
205
234
|
*/
|
|
206
|
-
type ErrorCode = CoreErrorCode;
|
|
235
|
+
type ErrorCode = CoreErrorCode | DatetimeErrorCode;
|
|
207
236
|
|
|
208
237
|
/**
|
|
209
238
|
* The engine's structured error type, the "Rust/Go-style, verbose, easy to
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.cjs';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* How a Datetime value is rendered.
|
|
3
5
|
*
|
|
@@ -15,6 +17,18 @@ type DateOutputFormat = "long" | "iso" | "dmy" | "mdy";
|
|
|
15
17
|
* This allows the engine to format values without depending on app-specific settings
|
|
16
18
|
*/
|
|
17
19
|
interface FormattingSettings {
|
|
20
|
+
/**
|
|
21
|
+
* The calendar backend a date is written out through: which local day and
|
|
22
|
+
* wall-clock time an instant shows as. Pass the same backend the engine
|
|
23
|
+
* was given as its `calendar` option, so a date displays in the zone it
|
|
24
|
+
* was computed in. Absent means the built-in `Date` backend, the process's
|
|
25
|
+
* own zone, which is what every engine computes with by default.
|
|
26
|
+
*
|
|
27
|
+
* A backend is an object of functions, so it cannot cross a `postMessage`
|
|
28
|
+
* boundary: a worker runtime takes its backend from `WorkerRuntimeOptions`
|
|
29
|
+
* and applies it to the formatting it receives.
|
|
30
|
+
*/
|
|
31
|
+
calendar?: CalendarBackend;
|
|
18
32
|
floatResult: {
|
|
19
33
|
decimalPlaces: number;
|
|
20
34
|
enableSeperator: boolean;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* How a Datetime value is rendered.
|
|
3
5
|
*
|
|
@@ -15,6 +17,18 @@ type DateOutputFormat = "long" | "iso" | "dmy" | "mdy";
|
|
|
15
17
|
* This allows the engine to format values without depending on app-specific settings
|
|
16
18
|
*/
|
|
17
19
|
interface FormattingSettings {
|
|
20
|
+
/**
|
|
21
|
+
* The calendar backend a date is written out through: which local day and
|
|
22
|
+
* wall-clock time an instant shows as. Pass the same backend the engine
|
|
23
|
+
* was given as its `calendar` option, so a date displays in the zone it
|
|
24
|
+
* was computed in. Absent means the built-in `Date` backend, the process's
|
|
25
|
+
* own zone, which is what every engine computes with by default.
|
|
26
|
+
*
|
|
27
|
+
* A backend is an object of functions, so it cannot cross a `postMessage`
|
|
28
|
+
* boundary: a worker runtime takes its backend from `WorkerRuntimeOptions`
|
|
29
|
+
* and applies it to the formatting it receives.
|
|
30
|
+
*/
|
|
31
|
+
calendar?: CalendarBackend;
|
|
18
32
|
floatResult: {
|
|
19
33
|
decimalPlaces: number;
|
|
20
34
|
enableSeperator: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { T as Token } from './Token-
|
|
1
|
+
import { T as Token } from './Token-D8f7yaz1.cjs';
|
|
2
|
+
import { E as EngineError } from './EngineError-C-kBwYlN.cjs';
|
|
2
3
|
|
|
3
4
|
/** Trie node for multi-word phrase matching. */
|
|
4
5
|
interface PhraseNode {
|
|
@@ -101,6 +102,14 @@ interface ScanLineResult {
|
|
|
101
102
|
tokens: Token[];
|
|
102
103
|
/** Inline solve spans found in this line (empty if none). */
|
|
103
104
|
inlineSolves: InlineSolveSpan[];
|
|
105
|
+
/**
|
|
106
|
+
* The structured error the tokeniser raised on this line, if it raised one
|
|
107
|
+
* (an unterminated string literal is the one it can raise today). The line
|
|
108
|
+
* carries no tokens then, and the rest of the document is unaffected: a
|
|
109
|
+
* half-typed quote used to escape {@link ExpressionLexer.scanDocument} as
|
|
110
|
+
* a throw and take every other line's result down with it.
|
|
111
|
+
*/
|
|
112
|
+
error?: EngineError;
|
|
104
113
|
}
|
|
105
114
|
/**
|
|
106
115
|
* A token, as the lexer produces it.
|
|
@@ -120,9 +129,19 @@ declare class LexerToken implements Token {
|
|
|
120
129
|
col: number;
|
|
121
130
|
/** See {@link Token.sourceEnd}. Set only on normalizer-fused tokens. */
|
|
122
131
|
sourceEnd?: number | undefined;
|
|
132
|
+
/** See {@link Token.fault}. Set only on a fused token standing for a run the engine refuses to read. */
|
|
133
|
+
fault?: {
|
|
134
|
+
readonly code: string;
|
|
135
|
+
readonly message: string;
|
|
136
|
+
} | undefined;
|
|
123
137
|
constructor(type: string, typeId: number, value: string, text: string, offset: number, lineBreaks: number, line: number, col: number,
|
|
124
138
|
/** See {@link Token.sourceEnd}. Set only on normalizer-fused tokens. */
|
|
125
|
-
sourceEnd?: number | undefined
|
|
139
|
+
sourceEnd?: number | undefined,
|
|
140
|
+
/** See {@link Token.fault}. Set only on a fused token standing for a run the engine refuses to read. */
|
|
141
|
+
fault?: {
|
|
142
|
+
readonly code: string;
|
|
143
|
+
readonly message: string;
|
|
144
|
+
} | undefined);
|
|
126
145
|
}
|
|
127
146
|
/**
|
|
128
147
|
* Plugin interface for extending the ExpressionLexer with custom tokens.
|
|
@@ -208,16 +227,6 @@ interface LexerVocabulary {
|
|
|
208
227
|
*/
|
|
209
228
|
declare class ExpressionLexer {
|
|
210
229
|
private static readonly CHAR_CLASS;
|
|
211
|
-
/**
|
|
212
|
-
* Configured TokenLookup from TokenClassRegistry. When set, replaces
|
|
213
|
-
* the internal keyword map and unit set with registry-built equivalents.
|
|
214
|
-
* Enables data-driven keyword/unit registration across locale keywords,
|
|
215
|
-
* provider keywords, and plugins.
|
|
216
|
-
*
|
|
217
|
-
* Set at construction time via the constructor parameter. Plugin-registered
|
|
218
|
-
* keywords/units (via registerVocabulary()) are checked alongside
|
|
219
|
-
* the configuredLookup, neither source is bypassed.
|
|
220
|
-
*/ private configuredLookup;
|
|
221
230
|
private input;
|
|
222
231
|
private pos;
|
|
223
232
|
private len;
|
|
@@ -227,7 +236,16 @@ declare class ExpressionLexer {
|
|
|
227
236
|
private keywordMap;
|
|
228
237
|
private mergedKeywords;
|
|
229
238
|
private mergedUnits;
|
|
230
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Who registered each plugin keyword, unit and two-character operator, in
|
|
241
|
+
* registration order. Two packages may claim the same word (the
|
|
242
|
+
* compatibility index warns, and the last registered wins, as before); the
|
|
243
|
+
* owner lists make unregistration exact, so removing one package hands the
|
|
244
|
+
* word back to the other rather than deleting it for both.
|
|
245
|
+
*/
|
|
246
|
+
private pluginKeywordOwners;
|
|
247
|
+
private pluginUnitOwners;
|
|
248
|
+
private pluginOperatorOwners;
|
|
231
249
|
private pluginOperators;
|
|
232
250
|
private pluginUnits;
|
|
233
251
|
private hasPluginOps;
|
|
@@ -235,7 +253,7 @@ declare class ExpressionLexer {
|
|
|
235
253
|
private locale;
|
|
236
254
|
/**
|
|
237
255
|
* Inline solve spans collected during the most recent tokenization pass.
|
|
238
|
-
* Populated by
|
|
256
|
+
* Populated by tokenizeInto() and consumed by scanDocument().
|
|
239
257
|
*/
|
|
240
258
|
_inlineSolveSpans: InlineSolveSpan[];
|
|
241
259
|
private pluginRawLinePatterns;
|
|
@@ -260,7 +278,14 @@ declare class ExpressionLexer {
|
|
|
260
278
|
private matchRawLine;
|
|
261
279
|
/** Rebuild merged keyword and unit collections after plugin registration. */
|
|
262
280
|
private rebuildMergedUnits;
|
|
263
|
-
|
|
281
|
+
/**
|
|
282
|
+
* @param localeCode - Locale whose keyword table seeds the lexer.
|
|
283
|
+
* @param _lookup - Ignored. The lexer built its keyword, unit and phrase
|
|
284
|
+
* tables from the locale and the registered packages and never read the
|
|
285
|
+
* lookup it was handed; the parameter stays so existing callers compile.
|
|
286
|
+
* @deprecated Removed in 3.0.
|
|
287
|
+
*/
|
|
288
|
+
constructor(localeCode?: string, _lookup?: TokenLookup);
|
|
264
289
|
/**
|
|
265
290
|
* Register a plugin to extend the lexer with custom tokens.
|
|
266
291
|
*
|
|
@@ -276,6 +301,10 @@ declare class ExpressionLexer {
|
|
|
276
301
|
* that conflicts with a built-in one.
|
|
277
302
|
*/
|
|
278
303
|
registerVocabulary(plugin: LexerVocabulary): void;
|
|
304
|
+
/** Record `owner`'s claim on `key`. The newest claim is the one in force. */
|
|
305
|
+
private claim;
|
|
306
|
+
/** Drop `owner`'s claim on `key`, and return the claim now in force, if any is left. */
|
|
307
|
+
private release;
|
|
279
308
|
/**
|
|
280
309
|
* Unregister a plugin, removing its custom tokens from the lexer.
|
|
281
310
|
*
|
|
@@ -307,9 +336,9 @@ declare class ExpressionLexer {
|
|
|
307
336
|
* lines that classifyLine() marks as having inline solves.
|
|
308
337
|
*
|
|
309
338
|
* Tokenization is scoped to each line by temporarily restricting
|
|
310
|
-
* `this.len` to the line end position, so
|
|
311
|
-
*
|
|
312
|
-
*
|
|
339
|
+
* `this.len` to the line end position, so tokenizeInto() naturally
|
|
340
|
+
* stops at the line boundary. After tokenization, `this.len` is
|
|
341
|
+
* restored and `this.pos` advances past the newline.
|
|
313
342
|
*
|
|
314
343
|
* @param text The full document text (with newlines).
|
|
315
344
|
* @returns Array of ScanLineResult, one per line, in document order.
|
|
@@ -318,9 +347,7 @@ declare class ExpressionLexer {
|
|
|
318
347
|
/**
|
|
319
348
|
* Tokenize an expression string into an array of Tokens.
|
|
320
349
|
*
|
|
321
|
-
*
|
|
322
|
-
* yielded tokens via Array.from(). For memory-sensitive use cases, prefer
|
|
323
|
-
* iterating the lexer directly with for...of to avoid array allocation.
|
|
350
|
+
* Runs {@link tokenizeInto} into a fresh array.
|
|
324
351
|
*
|
|
325
352
|
* Optimizations:
|
|
326
353
|
* - CHAR_CLASS jump table (Uint8Array) → switch on small integers
|
|
@@ -332,20 +359,31 @@ declare class ExpressionLexer {
|
|
|
332
359
|
*/
|
|
333
360
|
tokenizeAll(): Token[];
|
|
334
361
|
/**
|
|
335
|
-
*
|
|
336
|
-
*
|
|
362
|
+
* Scan the current input and append every token to `out`.
|
|
363
|
+
*
|
|
364
|
+
* This is the scanner itself: {@link tokenizeAll} and the iterator are
|
|
365
|
+
* thin wrappers over it. It pushes into an array the caller owns rather
|
|
366
|
+
* than yielding, because a generator paid a resume per token and
|
|
367
|
+
* `Array.from` a second pass on top, and because a caller that catches a
|
|
368
|
+
* tokeniser fault (highlighting a line with an unterminated quote) still
|
|
369
|
+
* holds the tokens read before it.
|
|
337
370
|
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
371
|
+
* IMPORTANT: `this.len` is read ONCE on entry (const len = this.len).
|
|
372
|
+
* `scanDocument()` relies on this to scope a pass to a single line by
|
|
373
|
+
* restricting `this.len` to the line end before calling. Do not re-read
|
|
374
|
+
* `this.len` mid-loop without also updating `scanDocument()`.
|
|
342
375
|
*
|
|
343
|
-
*
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
*
|
|
348
|
-
*
|
|
376
|
+
* @param out - The array to append to. Left as it was if the input is empty.
|
|
377
|
+
*/
|
|
378
|
+
tokenizeInto(out: Token[]): void;
|
|
379
|
+
/**
|
|
380
|
+
* Iterate the tokens of the current input.
|
|
381
|
+
*
|
|
382
|
+
* Runs {@link tokenizeInto} first, so the tokens are the same as before,
|
|
383
|
+
* but a fault part way through the line is thrown from the first
|
|
384
|
+
* `next()` rather than at the token it occurred on. A caller that wants
|
|
385
|
+
* the tokens read before a fault calls {@link tokenizeInto} with its own
|
|
386
|
+
* array.
|
|
349
387
|
*/
|
|
350
388
|
[Symbol.iterator](): Generator<Token, void, undefined>;
|
|
351
389
|
/**
|
|
@@ -456,6 +494,27 @@ declare class ExpressionLexer {
|
|
|
456
494
|
* `#12345` (length 5), `#ff0000zz` (trailing word) do not.
|
|
457
495
|
*/
|
|
458
496
|
private matchHexColourEnd;
|
|
497
|
+
/**
|
|
498
|
+
* Whether an inline-solve opener (`s` + backtick) occurs in `[from, end)`.
|
|
499
|
+
*
|
|
500
|
+
* Bounded by hand rather than written as `input.indexOf("s\`", from)`. This
|
|
501
|
+
* used to be the `indexOf` form with an `idx < end` check afterwards, which
|
|
502
|
+
* is correct but not bounded: when {@link scanDocument} is classifying,
|
|
503
|
+
* `this.input` is the whole document, so a line with no marker scanned to
|
|
504
|
+
* the END OF THE DOCUMENT before the check could reject the hit. Every line
|
|
505
|
+
* paid for every line after it, and a whole-document parse was quadratic in
|
|
506
|
+
* line count (measured at 28.9 us per line at 10,000 lines against 10.1 us
|
|
507
|
+
* at 1,000, and two thirds of the parse's self time in a profile). A prose
|
|
508
|
+
* document with many candidate `s` characters was worse still. The
|
|
509
|
+
* wikilink close in {@link indexOfWithin} had the same shape.
|
|
510
|
+
*/
|
|
511
|
+
private hasInlineSolveWithin;
|
|
512
|
+
/**
|
|
513
|
+
* `input.indexOf(needle, from)` restricted to `[from, end)`, returning -1
|
|
514
|
+
* when the needle does not occur wholly before `end`. See
|
|
515
|
+
* {@link hasInlineSolveWithin} for why the plain `indexOf` was not enough.
|
|
516
|
+
*/
|
|
517
|
+
private indexOfWithin;
|
|
459
518
|
private classifyFromPositions;
|
|
460
519
|
/**
|
|
461
520
|
* Classify a single line of markdown text.
|
|
@@ -530,11 +589,11 @@ declare class Lexer {
|
|
|
530
589
|
private tokenIdx;
|
|
531
590
|
/**
|
|
532
591
|
* @param localeCode - Locale code (e.g., "en", "de"). Defaults to "en".
|
|
533
|
-
* @param
|
|
534
|
-
*
|
|
535
|
-
*
|
|
592
|
+
* @param _tokenLookup - Ignored. The lexer never read the lookup it was
|
|
593
|
+
* handed; the parameter stays so existing callers compile.
|
|
594
|
+
* @deprecated Removed in 3.0.
|
|
536
595
|
*/
|
|
537
|
-
constructor(localeCode?: string,
|
|
596
|
+
constructor(localeCode?: string, _tokenLookup?: TokenLookup);
|
|
538
597
|
reset(input: string, state?: LexerState): void;
|
|
539
598
|
/**
|
|
540
599
|
* Classify a single line of markdown text (Phase B).
|