@blamejs/core 0.18.43 → 0.18.45
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/CHANGELOG.md +142 -0
- package/NOTICE +1 -1
- package/README.md +3 -2
- package/index.js +2 -0
- package/lib/chain-writer.js +103 -4
- package/lib/file-type.js +19 -2
- package/lib/framework-error.js +10 -0
- package/lib/gate-contract.js +255 -12
- package/lib/guard-all.js +1 -0
- package/lib/guard-archive.js +14 -0
- package/lib/guard-auth.js +1 -3
- package/lib/guard-country.js +480 -0
- package/lib/guard-csv.js +5 -0
- package/lib/guard-email.js +7 -7
- package/lib/guard-filename.js +11 -9
- package/lib/guard-graphql.js +1 -3
- package/lib/guard-html.js +6 -7
- package/lib/guard-image.js +15 -1
- package/lib/guard-json.js +3 -7
- package/lib/guard-jwt.js +8 -3
- package/lib/guard-markdown.js +946 -2
- package/lib/guard-oauth.js +1 -3
- package/lib/guard-pdf.js +8 -0
- package/lib/guard-regex.js +5 -4
- package/lib/guard-smtp-command.js +4 -2
- package/lib/guard-sql.js +10 -0
- package/lib/guard-svg.js +2 -1
- package/lib/guard-text.js +10 -0
- package/lib/guard-yaml.js +13 -2
- package/lib/mail-auth.js +12 -14
- package/lib/middleware/index.js +3 -0
- package/lib/middleware/shared-secret-header.js +334 -0
- package/lib/public-suffix.js +57 -0
- package/lib/time.js +282 -0
- package/lib/vendor/MANIFEST.json +13 -13
- package/lib/vendor/blamejs-pki.cjs +4069 -3138
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/public-suffix.js
CHANGED
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
*/
|
|
60
60
|
|
|
61
61
|
var nodeUrl = require("node:url");
|
|
62
|
+
var codepointClass = require("./codepoint-class");
|
|
62
63
|
var vendorData = require("./vendor-data");
|
|
63
64
|
var pslDataModule = require("./vendor/public-suffix-list.data");
|
|
64
65
|
var { PublicSuffixError } = require("./framework-error");
|
|
@@ -99,6 +100,32 @@ function _firstNonHostCharacter(name) {
|
|
|
99
100
|
return -1;
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
// The first character of an already-CONVERTED name that a domain may not
|
|
104
|
+
// contain, or -1.
|
|
105
|
+
//
|
|
106
|
+
// Run after `domainToASCII`, where the question has one answer: an
|
|
107
|
+
// internationalized label has become its `xn--` form by then, so a real name is
|
|
108
|
+
// letters, digits, hyphens and dots. `domainToASCII` is a UTS #46 MAPPER, not a
|
|
109
|
+
// hostname validator, and passes through 17 of the 31 non-LDH characters
|
|
110
|
+
// tested — `ex*ample.com`, `ex(ample.com` and `ex"ample.com` all came back as
|
|
111
|
+
// canonical domains, and a caller then compared one against a cookie domain, an
|
|
112
|
+
// SPF record or a residency table.
|
|
113
|
+
//
|
|
114
|
+
// Underscore is permitted. `_dmarc`, `_domainkey`, `_acme-challenge` and
|
|
115
|
+
// `_sip._tcp` are real DNS names, and whether to accept a service label is a
|
|
116
|
+
// POLICY question the framework already answers elsewhere — guardDomain's
|
|
117
|
+
// `underscorePolicy` refuses it at strict and allows it at permissive. This
|
|
118
|
+
// function normalizes a name; it does not judge one.
|
|
119
|
+
// Composed rather than hand-rolled: codepointClass owns the framework's
|
|
120
|
+
// character-set membership, caches the range table per distinct set, and reads
|
|
121
|
+
// as the rule it enforces. A charCodeAt loop here would be a fourth copy of a
|
|
122
|
+
// shape three files already have.
|
|
123
|
+
var _DOMAIN_CHARS = codepointClass.ASCII_ALNUM + "-._";
|
|
124
|
+
|
|
125
|
+
function _isLdhDomain(ascii) {
|
|
126
|
+
return codepointClass.isRunOf(ascii, _DOMAIN_CHARS, 1, ascii.length);
|
|
127
|
+
}
|
|
128
|
+
|
|
102
129
|
// The characters UTS #46 treats as a label separator, and therefore the ones
|
|
103
130
|
// that can mark the root of an absolute name. Scanned against Node's own
|
|
104
131
|
// mapping and found to be exactly this set across the BMP and the SMP.
|
|
@@ -172,6 +199,14 @@ function _normalizeInput(domain) {
|
|
|
172
199
|
throw _err("public-suffix/invalid-domain",
|
|
173
200
|
"publicSuffix: domain contains empty label");
|
|
174
201
|
}
|
|
202
|
+
// LDH, checked on the CONVERTED form — see _firstNonLdhCharacter for why the
|
|
203
|
+
// question only has one answer here.
|
|
204
|
+
if (!_isLdhDomain(ascii)) {
|
|
205
|
+
throw _err("public-suffix/invalid-domain",
|
|
206
|
+
"publicSuffix: domain contains a character that is not a letter, digit, " +
|
|
207
|
+
"hyphen, dot or underscore; domainToASCII MAPS such a name without " +
|
|
208
|
+
"validating it as a host, so `ex*ample.com` arrives here looking canonical");
|
|
209
|
+
}
|
|
175
210
|
// RFC 1035 §2.3.4 — 253 octets max for the wire form (255 minus the leading
|
|
176
211
|
// length byte and the root's null). This is the AUTHORITATIVE check, and it
|
|
177
212
|
// has to run on the converted name: an internationalized label grows into its
|
|
@@ -190,6 +225,28 @@ function _normalizeInput(domain) {
|
|
|
190
225
|
"publicSuffix: domain exceeds 253-octet RFC 1035 limit once converted " +
|
|
191
226
|
"to A-labels (" + withoutRoot + " octets)");
|
|
192
227
|
}
|
|
228
|
+
// RFC 1035 §2.3.4 bounds a LABEL at 63 octets as well as the whole name at
|
|
229
|
+
// 253, and only the second was checked. The argument is the one written above
|
|
230
|
+
// for the total: a 64-octet label cannot be put on the wire, and a caller
|
|
231
|
+
// handed one back cannot tell it apart from a name that can — this function
|
|
232
|
+
// returned `<64 a's>.com` as an organizational domain, and every resolver
|
|
233
|
+
// would refuse it. The rest of the framework already enforces both bounds
|
|
234
|
+
// (b.guardDomain, b.guardEmail, b.mailAuth); this was the one place that
|
|
235
|
+
// enforced one and not the other.
|
|
236
|
+
//
|
|
237
|
+
// Measured on the CONVERTED form for the same reason the total is: a 30-
|
|
238
|
+
// character internationalized label is well under 63 going in and can exceed
|
|
239
|
+
// it as an `xn--` A-label. The root marker, if still present, is not a label.
|
|
240
|
+
var labelSpan = ascii.slice(0, withoutRoot);
|
|
241
|
+
var labels = labelSpan.split(".");
|
|
242
|
+
for (var li = 0; li < labels.length; li += 1) {
|
|
243
|
+
if (labels[li].length > 63) {
|
|
244
|
+
throw _err("public-suffix/invalid-domain",
|
|
245
|
+
"publicSuffix: label " + JSON.stringify(labels[li].slice(0, 16) + "...") +
|
|
246
|
+
" is " + labels[li].length + " octets once converted to an A-label, over " +
|
|
247
|
+
"the 63-octet RFC 1035 limit");
|
|
248
|
+
}
|
|
249
|
+
}
|
|
193
250
|
// The root marker is stripped here when it was not an ASCII dot on the way
|
|
194
251
|
// in. UTS #46 maps U+3002, U+FF0E and U+FF61 to ".", so `münchen.example。`
|
|
195
252
|
// arrives with no trailing dot and leaves the conversion with one. Returning
|
package/lib/time.js
CHANGED
|
@@ -34,8 +34,15 @@
|
|
|
34
34
|
*/
|
|
35
35
|
var C = require("./constants");
|
|
36
36
|
var codepointClass = require("./codepoint-class");
|
|
37
|
+
var lazyRequire = require("./lazy-require");
|
|
38
|
+
var validateOpts = require("./validate-opts");
|
|
37
39
|
var { defineClass } = require("./framework-error");
|
|
38
40
|
|
|
41
|
+
// Lazy: the drift report is the only thing that needs it, and loading the
|
|
42
|
+
// observability stack at require-time would pull it into every consumer of a
|
|
43
|
+
// date formatter.
|
|
44
|
+
var observability = lazyRequire(function () { return require("./observability"); });
|
|
45
|
+
|
|
39
46
|
var TimeError = defineClass("TimeError", { alwaysPermanent: true });
|
|
40
47
|
|
|
41
48
|
var DEFAULT_TIMEZONE = "UTC";
|
|
@@ -821,6 +828,279 @@ function stripIsoMilliseconds(text) {
|
|
|
821
828
|
return text.slice(0, at) + "Z";
|
|
822
829
|
}
|
|
823
830
|
|
|
831
|
+
// ---------------------------------------------------------------------------
|
|
832
|
+
// Monotonic wall clock.
|
|
833
|
+
// ---------------------------------------------------------------------------
|
|
834
|
+
|
|
835
|
+
// How far ahead of the underlying source a clock may run before it says so.
|
|
836
|
+
// One second buys a thousand stamps inside a single millisecond — well past
|
|
837
|
+
// any realistic write burst — while keeping a recorded timestamp close enough
|
|
838
|
+
// to true time that an auditor reading it is not misled.
|
|
839
|
+
var DEFAULT_MAX_DRIFT_MS = C.TIME.seconds(1);
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* @primitive b.time.monotonicClock
|
|
843
|
+
* @signature b.time.monotonicClock(opts?)
|
|
844
|
+
* @since 0.18.44
|
|
845
|
+
* @status stable
|
|
846
|
+
* @related b.time.monotonicNow, b.chainWriter.create, b.ntpCheck.checkDrift
|
|
847
|
+
*
|
|
848
|
+
* An isolated clock whose `now()` never returns a value less than or equal to
|
|
849
|
+
* the one before it.
|
|
850
|
+
*
|
|
851
|
+
* `Date.now()` gives neither guarantee. It repeats when two writes land in the
|
|
852
|
+
* same millisecond, and it moves BACKWARDS when NTP steps the clock — the
|
|
853
|
+
* correction `b.ntpCheck` exists to detect. Anything that orders records by a
|
|
854
|
+
* timestamp inherits both problems: an append-only chain gets a row that
|
|
855
|
+
* appears to precede its predecessor, and keyset pagination over a timestamp
|
|
856
|
+
* column drops or repeats rows that share a millisecond.
|
|
857
|
+
*
|
|
858
|
+
* Three things the four-line hand-rolled version leaves out, and this settles:
|
|
859
|
+
*
|
|
860
|
+
* - **An injectable source.** `opts.source` defaults to `Date.now` but a test
|
|
861
|
+
* can hand over a scripted one, which a closure over `Date.now` cannot. It
|
|
862
|
+
* must return a SAFE-INTEGER count of milliseconds. A fractional clock such
|
|
863
|
+
* as `performance.timeOrigin + performance.now()` is refused rather than
|
|
864
|
+
* rounded: this primitive's whole promise is that the next value exceeds the
|
|
865
|
+
* last, and it keeps that promise by handing out `last + 1` when the source
|
|
866
|
+
* has not moved — arithmetic that needs an integer to stay exact.
|
|
867
|
+
* - **A floor that survives a restart.** Process memory resets to zero on
|
|
868
|
+
* restart or failover — precisely when a fresh node is syncing NTP and a
|
|
869
|
+
* backwards step is most likely. `observeFloor(ms)` seeds the guarantee from
|
|
870
|
+
* a value read back out of storage, and ignores anything below where the
|
|
871
|
+
* clock already is. It takes a NUMBER and refuses anything else, including
|
|
872
|
+
* the decimal string a Postgres `BIGINT` arrives as through most drivers:
|
|
873
|
+
* coercing a floor silently would accept `"abc"` as `NaN` and every later
|
|
874
|
+
* comparison against it as false, so the conversion is the caller's to make
|
|
875
|
+
* and to get wrong loudly.
|
|
876
|
+
* - **A ceiling on how far ahead of the source it may run.** A burst inside
|
|
877
|
+
* one millisecond walks the returned value into the future. Unbounded, that
|
|
878
|
+
* is a silently wrong timestamp; `maxDriftMs` is what makes it not silent.
|
|
879
|
+
*
|
|
880
|
+
* Passing the cap REPORTS — through `onDrift` when given, otherwise as the
|
|
881
|
+
* `time.monotonic.drift_exceeded` observability event — and keeps returning
|
|
882
|
+
* monotonic values. For the framework's own consumer, an append-only audit
|
|
883
|
+
* chain, a timestamp a few milliseconds optimistic is a smaller harm than a
|
|
884
|
+
* dropped row, and a dropped row is what an attacker who can step the clock
|
|
885
|
+
* would be aiming for. A caller whose property is timestamp ACCURACY rather
|
|
886
|
+
* than completeness asks for `strict: true` and gets a
|
|
887
|
+
* `time/monotonic-drift-cap` throw instead.
|
|
888
|
+
*
|
|
889
|
+
* The report never goes through `b.audit`: a clock that stamps audit rows and
|
|
890
|
+
* audits its own drift would call itself.
|
|
891
|
+
*
|
|
892
|
+
* @opts
|
|
893
|
+
* source: function, // default: Date.now — must return a SAFE-INTEGER number of ms
|
|
894
|
+
* maxDriftMs: number, // default: 1000 — lead over the source before it reports
|
|
895
|
+
* onDrift: function, // ({ driftMs, maxDriftMs, value, sourceMs, label }) — replaces the observability event
|
|
896
|
+
* strict: boolean, // default: false — true throws instead of reporting
|
|
897
|
+
* label: string, // default: "default" — names this clock in drift reports
|
|
898
|
+
*
|
|
899
|
+
* @example
|
|
900
|
+
* var clock = b.time.monotonicClock({ label: "device_event_log" });
|
|
901
|
+
* // Number(...) is not decoration: a Postgres BIGINT arrives as a decimal
|
|
902
|
+
* // STRING through most drivers, and observeFloor refuses one rather than
|
|
903
|
+
* // coercing it — a floor is too important to guess at.
|
|
904
|
+
* clock.observeFloor(Number(tipRow.recordedAt)); // durable, read from storage
|
|
905
|
+
* var recordedAt = clock.now();
|
|
906
|
+
* // → strictly greater than tipRow.recordedAt, whatever the wall clock did
|
|
907
|
+
*/
|
|
908
|
+
function monotonicClock(opts) {
|
|
909
|
+
opts = opts || {};
|
|
910
|
+
validateOpts(opts, ["source", "maxDriftMs", "onDrift", "strict", "label"],
|
|
911
|
+
"b.time.monotonicClock");
|
|
912
|
+
|
|
913
|
+
validateOpts.shape(opts, {
|
|
914
|
+
source: { rule: "optional-function", code: "time/bad-source" },
|
|
915
|
+
maxDriftMs: { rule: "optional-non-negative", code: "time/bad-max-drift" },
|
|
916
|
+
onDrift: { rule: "optional-function", code: "time/bad-on-drift" },
|
|
917
|
+
strict: { rule: "optional-boolean", code: "time/bad-strict" },
|
|
918
|
+
label: { rule: "optional-string", code: "time/bad-label" },
|
|
919
|
+
}, "b.time.monotonicClock", TimeError, "time/bad-opts");
|
|
920
|
+
|
|
921
|
+
var source = opts.source == null ? Date.now : opts.source;
|
|
922
|
+
var maxDriftMs = opts.maxDriftMs == null ? DEFAULT_MAX_DRIFT_MS : opts.maxDriftMs;
|
|
923
|
+
var onDrift = opts.onDrift == null ? null : opts.onDrift;
|
|
924
|
+
var strict = opts.strict === true;
|
|
925
|
+
var label = opts.label == null ? "default" : opts.label;
|
|
926
|
+
|
|
927
|
+
var last = 0;
|
|
928
|
+
var lastSourceMs = 0;
|
|
929
|
+
var reporting = false;
|
|
930
|
+
|
|
931
|
+
function _report(info) {
|
|
932
|
+
// A reporter that calls now() re-enters here, and the re-entrant call drifts
|
|
933
|
+
// by construction - it is one millisecond further ahead than the call that
|
|
934
|
+
// triggered the report. Reporting that would recurse until the stack ran
|
|
935
|
+
// out, so the outermost report is the one that speaks for the burst.
|
|
936
|
+
if (reporting) return;
|
|
937
|
+
reporting = true;
|
|
938
|
+
try { _reportOnce(info); } finally { reporting = false; }
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
function _reportOnce(info) {
|
|
942
|
+
if (onDrift) {
|
|
943
|
+
// The caller's reporter is theirs to get wrong; a throw from it must not
|
|
944
|
+
// decide whether the timestamp was issued.
|
|
945
|
+
try { onDrift(info); } catch (_e) { /* drop-silent — see the block comment above */ }
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
// Never b.audit: an audit row needs a timestamp, which needs this clock.
|
|
949
|
+
try {
|
|
950
|
+
observability().safeEvent("time.monotonic.drift_exceeded", info.driftMs, {
|
|
951
|
+
clock: info.label,
|
|
952
|
+
});
|
|
953
|
+
} catch (_e) { /* drop-silent — an observability failure must not stop the clock */ }
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
function now() {
|
|
957
|
+
// A drift report runs caller code in the middle of issuing a value. A
|
|
958
|
+
// reporter that asks this same clock for another one gets a HIGHER value
|
|
959
|
+
// and returns it BEFORE the call that triggered the report returns its
|
|
960
|
+
// lower one - so a callback that stamps its own log line records the drift
|
|
961
|
+
// at a later instant than the event it describes, which is time running
|
|
962
|
+
// backwards in the record this clock exists to keep straight.
|
|
963
|
+
//
|
|
964
|
+
// Refusing is the honest answer, and it costs the reporter nothing: the
|
|
965
|
+
// value being reported on is already in `info.value`. The throw is caught
|
|
966
|
+
// by _report's drop-silent wrapper, so it cannot fail the append that
|
|
967
|
+
// triggered the report. A DIFFERENT clock is unaffected - this is per
|
|
968
|
+
// instance, not a global lock.
|
|
969
|
+
if (reporting) {
|
|
970
|
+
throw new TimeError("time/monotonic-reentrant",
|
|
971
|
+
"b.time.monotonicClock(" + label + "): now() was called from this " +
|
|
972
|
+
"clock's own drift report. The value being reported on is in " +
|
|
973
|
+
"info.value; asking for a new one here would return a later " +
|
|
974
|
+
"timestamp than the event it describes.");
|
|
975
|
+
}
|
|
976
|
+
var t = source();
|
|
977
|
+
// Number.isSafeInteger, not isFinite: past 2^53 the value has ALREADY been
|
|
978
|
+
// rounded before it arrives, and `last + 1` stops increasing there - the
|
|
979
|
+
// addition saturates, two calls return the same number, and the one
|
|
980
|
+
// guarantee this primitive makes fails silently. Refuse instead.
|
|
981
|
+
if (typeof t !== "number" || !Number.isSafeInteger(t)) {
|
|
982
|
+
throw new TimeError("time/monotonic-bad-source",
|
|
983
|
+
"b.time.monotonicClock: the clock source returned " +
|
|
984
|
+
(typeof t === "number" ? String(t) : typeof t) +
|
|
985
|
+
" rather than a safe integer number of epoch milliseconds");
|
|
986
|
+
}
|
|
987
|
+
lastSourceMs = t;
|
|
988
|
+
var value = t > last ? t : last + 1;
|
|
989
|
+
// The invariant, checked rather than assumed. Reachable only at the
|
|
990
|
+
// safe-integer ceiling, which the input screens above already refuse - so
|
|
991
|
+
// this is the backstop that cannot be bypassed by a future caller finding
|
|
992
|
+
// another way to raise the floor.
|
|
993
|
+
if (!(value > last) || !Number.isSafeInteger(value)) {
|
|
994
|
+
throw new TimeError("time/monotonic-exhausted",
|
|
995
|
+
"b.time.monotonicClock(" + label + "): the next monotonic value would " +
|
|
996
|
+
"not exceed the last (" + last + "), so the guarantee cannot be kept. " +
|
|
997
|
+
"The clock has reached the safe-integer ceiling; a floor read from " +
|
|
998
|
+
"storage is the only way to get here.");
|
|
999
|
+
}
|
|
1000
|
+
var driftMs = value - t;
|
|
1001
|
+
if (driftMs > maxDriftMs) {
|
|
1002
|
+
var info = {
|
|
1003
|
+
driftMs: driftMs, maxDriftMs: maxDriftMs,
|
|
1004
|
+
value: value, sourceMs: t, label: label,
|
|
1005
|
+
};
|
|
1006
|
+
if (strict) {
|
|
1007
|
+
// Throw BEFORE advancing, so a caller that never received the value
|
|
1008
|
+
// cannot have it walk the floor further out of reach on every retry.
|
|
1009
|
+
throw new TimeError("time/monotonic-drift-cap",
|
|
1010
|
+
"b.time.monotonicClock(" + label + "): the monotonic value is " + driftMs +
|
|
1011
|
+
"ms ahead of the clock source, past the " + maxDriftMs + "ms cap. Either the " +
|
|
1012
|
+
"write rate exceeds one row per millisecond or the system clock stepped " +
|
|
1013
|
+
"backwards; b.ntpCheck.checkDrift() distinguishes them.");
|
|
1014
|
+
}
|
|
1015
|
+
// Advance BEFORE the reporter runs. _report hands control to caller code,
|
|
1016
|
+
// and a reporter that calls now() re-enters this function; if the floor
|
|
1017
|
+
// had not moved yet the re-entrant call would compute the SAME value from
|
|
1018
|
+
// the same `last` and two callers would hold one timestamp - exactly the
|
|
1019
|
+
// collision this clock exists to prevent. The strict throw above still
|
|
1020
|
+
// precedes the advance, because there the value is never issued at all.
|
|
1021
|
+
last = value;
|
|
1022
|
+
_report(info);
|
|
1023
|
+
return value;
|
|
1024
|
+
}
|
|
1025
|
+
last = value;
|
|
1026
|
+
return value;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// Raise the floor to a value read back out of storage. Lower values are
|
|
1030
|
+
// ignored rather than refused: a stale replica or an out-of-order read must
|
|
1031
|
+
// not be able to rewind a clock that has already moved past it.
|
|
1032
|
+
function observeFloor(ms) {
|
|
1033
|
+
// A safe integer, not merely finite. This value comes from STORAGE - the
|
|
1034
|
+
// chain writer seeds it from a persisted recordedAt column - so it is the
|
|
1035
|
+
// one input a caller does not compose themselves, and a value past 2^53
|
|
1036
|
+
// would push the clock to a ceiling where `last + 1` saturates and the
|
|
1037
|
+
// monotonic guarantee quietly stops holding.
|
|
1038
|
+
if (typeof ms !== "number" || !Number.isSafeInteger(ms)) {
|
|
1039
|
+
throw new TimeError("time/bad-floor",
|
|
1040
|
+
"b.time.monotonicClock.observeFloor: expected a safe-integer number of " +
|
|
1041
|
+
"epoch milliseconds; got " + (typeof ms === "number" ? String(ms) : typeof ms));
|
|
1042
|
+
}
|
|
1043
|
+
if (ms < 0) {
|
|
1044
|
+
throw new TimeError("time/bad-floor",
|
|
1045
|
+
"b.time.monotonicClock.observeFloor: a floor cannot be negative; got " + ms);
|
|
1046
|
+
}
|
|
1047
|
+
// MAX_SAFE_INTEGER is itself a safe integer, so the check above admits it -
|
|
1048
|
+
// and a clock sitting exactly there has no next value: MAX + 1 is not
|
|
1049
|
+
// representable and rounds back to MAX. Refuse the boundary too, so the
|
|
1050
|
+
// guarantee never depends on there being one more tick available.
|
|
1051
|
+
if (ms >= Number.MAX_SAFE_INTEGER) {
|
|
1052
|
+
throw new TimeError("time/bad-floor",
|
|
1053
|
+
"b.time.monotonicClock.observeFloor: a floor at or past " +
|
|
1054
|
+
"Number.MAX_SAFE_INTEGER leaves no representable next value, so the " +
|
|
1055
|
+
"monotonic guarantee could not be kept; got " + ms);
|
|
1056
|
+
}
|
|
1057
|
+
if (ms > last) last = ms;
|
|
1058
|
+
return last;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
return {
|
|
1062
|
+
now: now,
|
|
1063
|
+
observeFloor: observeFloor,
|
|
1064
|
+
lastValue: function () { return last; },
|
|
1065
|
+
driftMs: function () { return last > lastSourceMs ? last - lastSourceMs : 0; },
|
|
1066
|
+
label: label,
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
var _sharedMonotonic = monotonicClock({ label: "shared" });
|
|
1071
|
+
|
|
1072
|
+
/**
|
|
1073
|
+
* @primitive b.time.monotonicNow
|
|
1074
|
+
* @signature b.time.monotonicNow()
|
|
1075
|
+
* @since 0.18.44
|
|
1076
|
+
* @status stable
|
|
1077
|
+
* @related b.time.monotonicClock
|
|
1078
|
+
*
|
|
1079
|
+
* The process-wide monotonic clock: epoch milliseconds that never repeat and
|
|
1080
|
+
* never move backwards, whatever `Date.now()` does. The shape most callers
|
|
1081
|
+
* want — one shared sequence, so two unrelated call sites in the same process
|
|
1082
|
+
* cannot mint the same value.
|
|
1083
|
+
*
|
|
1084
|
+
* Takes no arguments. A caller who needs an injectable source, a durable
|
|
1085
|
+
* floor, a different drift cap, or a sequence isolated from everyone else's
|
|
1086
|
+
* builds their own with `b.time.monotonicClock`; configuring a shared clock
|
|
1087
|
+
* from one call site would silently change every other site's behaviour.
|
|
1088
|
+
*
|
|
1089
|
+
* @example
|
|
1090
|
+
* var a = b.time.monotonicNow();
|
|
1091
|
+
* var b2 = b.time.monotonicNow();
|
|
1092
|
+
* // → b2 > a, even inside the same millisecond
|
|
1093
|
+
*/
|
|
1094
|
+
function monotonicNow() {
|
|
1095
|
+
if (arguments.length > 0) {
|
|
1096
|
+
throw new TimeError("time/monotonic-now-takes-no-opts",
|
|
1097
|
+
"b.time.monotonicNow() takes no arguments — it is one shared sequence, and " +
|
|
1098
|
+
"configuring it from one call site would change every other. Use " +
|
|
1099
|
+
"b.time.monotonicClock(opts) for a clock of your own.");
|
|
1100
|
+
}
|
|
1101
|
+
return _sharedMonotonic.now();
|
|
1102
|
+
}
|
|
1103
|
+
|
|
824
1104
|
module.exports = {
|
|
825
1105
|
toParts: toParts,
|
|
826
1106
|
format: format,
|
|
@@ -836,5 +1116,7 @@ module.exports = {
|
|
|
836
1116
|
readDateTime: readDateTime,
|
|
837
1117
|
toIso8601NoMs: toIso8601NoMs,
|
|
838
1118
|
stripIsoMilliseconds: stripIsoMilliseconds,
|
|
1119
|
+
monotonicClock: monotonicClock,
|
|
1120
|
+
monotonicNow: monotonicNow,
|
|
839
1121
|
TimeError: TimeError,
|
|
840
1122
|
};
|
package/lib/vendor/MANIFEST.json
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"server": "sha256:f3325f480cb8eb814fcb0baaa19336cbbf2b993f48624c6aa9600ffd69d0be5e",
|
|
22
22
|
"browser": "sha256:0ffd91540bcb586a29b56e52ee1c29df69097b50776beb4036a07558f7a4e12e"
|
|
23
23
|
},
|
|
24
|
-
"refreshedAt": "2026-08-
|
|
24
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z"
|
|
25
25
|
},
|
|
26
26
|
"@noble/hashes": {
|
|
27
27
|
"version": "2.3.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"hashes": {
|
|
49
49
|
"browser": "sha256:dfe4b7ae3c9880e388c8da4b68f44742b229b53afacd1e674179527e33da62b0"
|
|
50
50
|
},
|
|
51
|
-
"refreshedAt": "2026-08-
|
|
51
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z"
|
|
52
52
|
},
|
|
53
53
|
"@noble/curves": {
|
|
54
54
|
"version": "2.3.0",
|
|
@@ -65,12 +65,12 @@
|
|
|
65
65
|
"server": "lib/vendor/noble-curves.cjs"
|
|
66
66
|
},
|
|
67
67
|
"bundler": "esbuild --format=cjs --platform=node",
|
|
68
|
-
"bundledAt": "2026-08-
|
|
68
|
+
"bundledAt": "2026-08-21T00:00:00Z",
|
|
69
69
|
"cpe": "cpe:2.3:a:paulmillr:noble-curves:2.3.0:*:*:*:*:node.js:*:*",
|
|
70
70
|
"hashes": {
|
|
71
71
|
"server": "sha256:b5fe88d1ea780d0581dee6145d666f89d46fc9531b5db35db2e5b16627840890"
|
|
72
72
|
},
|
|
73
|
-
"refreshedAt": "2026-08-
|
|
73
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z",
|
|
74
74
|
"components": {
|
|
75
75
|
"@noble/hashes": {
|
|
76
76
|
"url": "https://github.com/paulmillr/noble-hashes",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"server": "sha256:fab7ebe5737793862c473444f4ee5912f79dd1edec86683acbb4eecbca0f5892",
|
|
115
115
|
"browser": "sha256:cae1d5bbdc7184b202b6ca68df6e1db7b0d0f668c77809ded189ca7f271accc9"
|
|
116
116
|
},
|
|
117
|
-
"refreshedAt": "2026-08-
|
|
117
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z",
|
|
118
118
|
"components": {
|
|
119
119
|
"@noble/hashes": {
|
|
120
120
|
"url": "https://github.com/paulmillr/noble-hashes",
|
|
@@ -148,7 +148,7 @@
|
|
|
148
148
|
},
|
|
149
149
|
"runtime_artifact": "lib/vendor/common-passwords-top-10000.data.js",
|
|
150
150
|
"integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
|
|
151
|
-
"refreshedAt": "2026-08-
|
|
151
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z"
|
|
152
152
|
},
|
|
153
153
|
"bimi-trust-anchors": {
|
|
154
154
|
"version": "operator-managed",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
},
|
|
174
174
|
"runtime_artifact": "lib/vendor/bimi-trust-anchors.data.js",
|
|
175
175
|
"integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
|
|
176
|
-
"refreshedAt": "2026-08-
|
|
176
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z"
|
|
177
177
|
},
|
|
178
178
|
"publicsuffix-list": {
|
|
179
179
|
"version": "master",
|
|
@@ -193,10 +193,10 @@
|
|
|
193
193
|
},
|
|
194
194
|
"runtime_artifact": "lib/vendor/public-suffix-list.data.js",
|
|
195
195
|
"integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
|
|
196
|
-
"refreshedAt": "2026-08-
|
|
196
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z"
|
|
197
197
|
},
|
|
198
198
|
"@blamejs/pki": {
|
|
199
|
-
"version": "0.5.
|
|
199
|
+
"version": "0.5.25",
|
|
200
200
|
"license": "Apache-2.0",
|
|
201
201
|
"author": "blamejs",
|
|
202
202
|
"source": "https://github.com/blamejs/pki",
|
|
@@ -216,12 +216,12 @@
|
|
|
216
216
|
"server": "lib/vendor/blamejs-pki.cjs"
|
|
217
217
|
},
|
|
218
218
|
"bundler": "esbuild --format=cjs --platform=node --external:crypto --external:node:crypto",
|
|
219
|
-
"bundledAt": "2026-08-
|
|
220
|
-
"cpe": "cpe:2.3:a:blamejs:pki:0.5.
|
|
219
|
+
"bundledAt": "2026-08-21T00:00:00Z",
|
|
220
|
+
"cpe": "cpe:2.3:a:blamejs:pki:0.5.25:*:*:*:*:node.js:*:*",
|
|
221
221
|
"hashes": {
|
|
222
|
-
"server": "sha256:
|
|
222
|
+
"server": "sha256:4e64654dfddb16742f615f24a4e8892286495d94ae29597cdc3e988122f3ef4a"
|
|
223
223
|
},
|
|
224
|
-
"refreshedAt": "2026-08-
|
|
224
|
+
"refreshedAt": "2026-08-22T03:19:31.188Z"
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
}
|