@lagless/misc 0.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export declare const now: () => number;
2
+ //# sourceMappingURL=now.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"now.d.ts","sourceRoot":"","sources":["../../src/lib/now.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,GAAG,EAAE,MAAM,MAMd,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const now = typeof globalThis.performance?.now === 'function'
2
+ ? globalThis.performance.now.bind(globalThis.performance)
3
+ : (() => {
4
+ const { performance } = require('node:perf_hooks');
5
+ return performance.now.bind(performance);
6
+ })();
@@ -0,0 +1,27 @@
1
+ export declare class PhaseNudger {
2
+ private readonly _frameLength;
3
+ private readonly _maxNudgePerFrame;
4
+ private _phaseDebtMs;
5
+ private _isActive;
6
+ constructor(_frameLength: number, _maxNudgePerFrame: number);
7
+ get isActive(): boolean;
8
+ get currentDebtMs(): number;
9
+ /**
10
+ * Activates the nudger. Call this when ClockSync becomes ready.
11
+ */
12
+ activate(): void;
13
+ /**
14
+ * Call on every server tick hint (after ClockSync is ready).
15
+ */
16
+ onServerTickHint(serverTick: number, localTick: number): void;
17
+ /**
18
+ * Resets debt to zero. Use when doing hard time sync.
19
+ */
20
+ reset(): void;
21
+ /**
22
+ * Drain a small portion of phase debt each frame.
23
+ * @returns milliseconds to add to accumulatedTime
24
+ */
25
+ drain(): number;
26
+ }
27
+ //# sourceMappingURL=phase-nudger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phase-nudger.d.ts","sourceRoot":"","sources":["../../src/lib/phase-nudger.ts"],"names":[],"mappings":"AAMA,qBAAa,WAAW;IAKpB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IALpC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,SAAS,CAAS;gBAGP,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM;IAG5C,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED;;OAEG;IACI,QAAQ,IAAI,IAAI;IAKvB;;OAEG;IACI,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAyBpE;;OAEG;IACI,KAAK,IAAI,IAAI;IAIpB;;;OAGG;IACI,KAAK,IAAI,MAAM;CA6BvB"}
@@ -0,0 +1,84 @@
1
+ import { createLogger } from './logger.js';
2
+ const log = createLogger('PhaseNudger');
3
+ const LARGE_DEBT_THRESHOLD_MS = 50;
4
+ const MAX_SINGLE_CORRECTION_MS = 5_000;
5
+ export class PhaseNudger {
6
+ _frameLength;
7
+ _maxNudgePerFrame;
8
+ _phaseDebtMs = 0;
9
+ _isActive = false;
10
+ constructor(_frameLength, _maxNudgePerFrame) {
11
+ this._frameLength = _frameLength;
12
+ this._maxNudgePerFrame = _maxNudgePerFrame;
13
+ }
14
+ get isActive() {
15
+ return this._isActive;
16
+ }
17
+ get currentDebtMs() {
18
+ return this._phaseDebtMs;
19
+ }
20
+ /**
21
+ * Activates the nudger. Call this when ClockSync becomes ready.
22
+ */
23
+ activate() {
24
+ this._isActive = true;
25
+ log.info('Activated');
26
+ }
27
+ /**
28
+ * Call on every server tick hint (after ClockSync is ready).
29
+ */
30
+ onServerTickHint(serverTick, localTick) {
31
+ if (!this._isActive) {
32
+ return;
33
+ }
34
+ const dTicks = (serverTick - localTick) | 0;
35
+ const correctionMs = dTicks * this._frameLength;
36
+ // Reject unreasonably large corrections (likely bad data)
37
+ if (Math.abs(correctionMs) > MAX_SINGLE_CORRECTION_MS) {
38
+ log.warn(`Rejected large correction: ${correctionMs.toFixed(0)}ms (${dTicks} ticks)`);
39
+ return;
40
+ }
41
+ // Accumulate (not replace) - smooth out fluctuations
42
+ // Using weighted accumulation to prevent oscillation
43
+ const weight = 0.3;
44
+ this._phaseDebtMs = this._phaseDebtMs * (1 - weight) + correctionMs * weight;
45
+ // console.log(
46
+ // `[PhaseNudger] Hint: ${dTicks} ticks, ` +
47
+ // `debt: ${this._phaseDebtMs.toFixed(1)}ms`
48
+ // );
49
+ }
50
+ /**
51
+ * Resets debt to zero. Use when doing hard time sync.
52
+ */
53
+ reset() {
54
+ this._phaseDebtMs = 0;
55
+ }
56
+ /**
57
+ * Drain a small portion of phase debt each frame.
58
+ * @returns milliseconds to add to accumulatedTime
59
+ */
60
+ drain() {
61
+ if (!this._isActive || this._phaseDebtMs === 0) {
62
+ return 0;
63
+ }
64
+ const absDebt = Math.abs(this._phaseDebtMs);
65
+ // For large debt: drain faster but still limited
66
+ // For small debt: drain slowly for smoothness
67
+ let drainAmount;
68
+ if (absDebt >= LARGE_DEBT_THRESHOLD_MS) {
69
+ // Drain up to 50% of large debt per frame, but not more than frameLength
70
+ drainAmount = Math.min(absDebt * 0.5, this._frameLength);
71
+ }
72
+ else {
73
+ // Drain small amounts gradually
74
+ drainAmount = Math.min(absDebt, this._maxNudgePerFrame);
75
+ }
76
+ drainAmount *= Math.sign(this._phaseDebtMs);
77
+ this._phaseDebtMs -= drainAmount;
78
+ // Snap to zero if very small
79
+ if (Math.abs(this._phaseDebtMs) < 0.1) {
80
+ this._phaseDebtMs = 0;
81
+ }
82
+ return drainAmount;
83
+ }
84
+ }
@@ -0,0 +1,11 @@
1
+ export declare class RingBuffer<T> {
2
+ protected readonly _buffer: T[];
3
+ protected readonly _size: number;
4
+ private _pos;
5
+ constructor(size: number);
6
+ add(item: T): number;
7
+ get(atIdx: number): T | undefined;
8
+ [Symbol.iterator](): ArrayIterator<T>;
9
+ clear(): void;
10
+ }
11
+ //# sourceMappingURL=ring-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/lib/ring-buffer.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAU,CAAC,CAAC;IACvB,SAAS,CAAC,QAAQ,CAAC,OAAO,MAAgB;IAC1C,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACjC,OAAO,CAAC,IAAI,CAAK;gBAEL,IAAI,EAAE,MAAM;IAOjB,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM;IAQpB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIjC,CAAC,MAAM,CAAC,QAAQ,CAAC;IAIjB,KAAK,IAAI,IAAI;CAIrB"}
@@ -0,0 +1,27 @@
1
+ export class RingBuffer {
2
+ _buffer = new Array;
3
+ _size;
4
+ _pos = 0;
5
+ constructor(size) {
6
+ if (size < 0) {
7
+ throw new RangeError('The size does not allow negative values.');
8
+ }
9
+ this._size = size;
10
+ }
11
+ add(item) {
12
+ const insertAtIdx = this._pos;
13
+ this._buffer[insertAtIdx] = item;
14
+ this._pos = (insertAtIdx + 1) % this._size;
15
+ return insertAtIdx;
16
+ }
17
+ get(atIdx) {
18
+ return this._buffer[atIdx];
19
+ }
20
+ [Symbol.iterator]() {
21
+ return this._buffer[Symbol.iterator]();
22
+ }
23
+ clear() {
24
+ this._buffer.length = 0;
25
+ this._pos = 0;
26
+ }
27
+ }
@@ -0,0 +1,18 @@
1
+ import { PhaseNudger } from './phase-nudger.js';
2
+ export declare class SimulationClock {
3
+ private _startedTime;
4
+ private _accumulatedTime;
5
+ readonly phaseNudger: PhaseNudger;
6
+ constructor(frameLength: number, maxNudgePerFrame: number);
7
+ get startedTime(): number;
8
+ get accumulatedTime(): number;
9
+ getElapsedTime: () => number;
10
+ start(): void;
11
+ update(dt: number): void;
12
+ /**
13
+ * Jump accumulated time to a specific value.
14
+ * Used for late-join to sync with server tick.
15
+ */
16
+ setAccumulatedTime(ms: number): void;
17
+ }
18
+ //# sourceMappingURL=simulation-clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulation-clock.d.ts","sourceRoot":"","sources":["../../src/lib/simulation-clock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,gBAAgB,CAAK;IAE7B,SAAgB,WAAW,EAAE,WAAW,CAAC;gBAGvC,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM;IAK1B,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,eAAe,IAAI,MAAM,CAEnC;IAEM,cAAc,QAAO,MAAM,CAKjC;IAEM,KAAK,IAAI,IAAI;IAQb,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI/B;;;OAGG;IACI,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAI5C"}
@@ -0,0 +1,40 @@
1
+ import { now } from './now.js';
2
+ import { PhaseNudger } from './phase-nudger.js';
3
+ export class SimulationClock {
4
+ _startedTime = 0;
5
+ _accumulatedTime = 0;
6
+ phaseNudger;
7
+ constructor(frameLength, maxNudgePerFrame) {
8
+ this.phaseNudger = new PhaseNudger(frameLength, maxNudgePerFrame);
9
+ }
10
+ get startedTime() {
11
+ return this._startedTime;
12
+ }
13
+ get accumulatedTime() {
14
+ return this._accumulatedTime;
15
+ }
16
+ getElapsedTime = () => {
17
+ if (this._startedTime === 0) {
18
+ throw new Error('SimulationClock has not been started yet.');
19
+ }
20
+ return now() - this._startedTime;
21
+ };
22
+ start() {
23
+ if (this._startedTime !== 0) {
24
+ throw new Error('SimulationClock has already been started.');
25
+ }
26
+ this._startedTime = now();
27
+ this._accumulatedTime = 0;
28
+ }
29
+ update(dt) {
30
+ this._accumulatedTime += dt + this.phaseNudger.drain();
31
+ }
32
+ /**
33
+ * Jump accumulated time to a specific value.
34
+ * Used for late-join to sync with server tick.
35
+ */
36
+ setAccumulatedTime(ms) {
37
+ this._accumulatedTime = ms;
38
+ this.phaseNudger.reset();
39
+ }
40
+ }
@@ -0,0 +1,18 @@
1
+ export declare class SnapshotHistory<T> {
2
+ private readonly _maxSize;
3
+ private readonly _ticks;
4
+ private readonly _snapshots;
5
+ private _head;
6
+ private _count;
7
+ private _lastTick;
8
+ constructor(maxSize: number);
9
+ set(tick: number, snapshot: T): void;
10
+ getNearest(tick: number): T;
11
+ /**
12
+ * Remove all snapshots with tick >= given tick.
13
+ * After this call you can safely write new snapshots starting from that tick.
14
+ */
15
+ rollback(tick: number): void;
16
+ private indexAt;
17
+ }
18
+ //# sourceMappingURL=snapshot-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-history.d.ts","sourceRoot":"","sources":["../../src/lib/snapshot-history.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAe,CAAC,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAG/C,OAAO,CAAC,KAAK,CAAK;IAElB,OAAO,CAAC,MAAM,CAAK;IAEnB,OAAO,CAAC,SAAS,CAAa;gBAElB,OAAO,EAAE,MAAM;IAUpB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI;IAkCpC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC;IAuClC;;;OAGG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAkCnC,OAAO,CAAC,OAAO;CAKhB"}
@@ -0,0 +1,121 @@
1
+ export class SnapshotHistory {
2
+ _maxSize;
3
+ _ticks;
4
+ _snapshots;
5
+ // Index of the oldest element in the ring buffer
6
+ _head = 0;
7
+ // Number of stored elements (<= maxSize)
8
+ _count = 0;
9
+ // Last inserted tick (to enforce monotonicity)
10
+ _lastTick = -Infinity;
11
+ constructor(maxSize) {
12
+ if (!Number.isInteger(maxSize) || maxSize <= 0) {
13
+ throw new Error('maxSize must be a positive integer');
14
+ }
15
+ this._maxSize = maxSize;
16
+ this._ticks = new Array(maxSize);
17
+ this._snapshots = new Array(maxSize);
18
+ }
19
+ set(tick, snapshot) {
20
+ // Enforce non-decreasing ticks for fast structure
21
+ if (tick < this._lastTick) {
22
+ throw new Error('Ticks must be non-decreasing. Call rollback() before writing older ticks.');
23
+ }
24
+ // If tick is the same as last one - just overwrite the last snapshot
25
+ if (tick === this._lastTick && this._count > 0) {
26
+ const lastLogicalIndex = this._count - 1;
27
+ const lastPhysicalIndex = this.indexAt(lastLogicalIndex);
28
+ this._ticks[lastPhysicalIndex] = tick;
29
+ this._snapshots[lastPhysicalIndex] = snapshot;
30
+ return;
31
+ }
32
+ this._lastTick = tick;
33
+ // Choose physical index where we will write new snapshot
34
+ let idx;
35
+ if (this._count < this._maxSize) {
36
+ // There is still free space: append after the last element
37
+ idx = this.indexAt(this._count);
38
+ this._count++;
39
+ }
40
+ else {
41
+ // Buffer is full: overwrite the oldest element (at head)
42
+ idx = this._head;
43
+ // Move head forward
44
+ this._head = (this._head + 1) % this._maxSize;
45
+ }
46
+ this._ticks[idx] = tick;
47
+ this._snapshots[idx] = snapshot;
48
+ }
49
+ getNearest(tick) {
50
+ if (this._count === 0) {
51
+ throw new Error('History is empty');
52
+ }
53
+ // Smallest tick (oldest snapshot)
54
+ const firstTick = this._ticks[this.indexAt(0)];
55
+ if (tick <= firstTick) {
56
+ // No snapshot with tick < requested tick
57
+ throw new Error('No snapshot with tick less than requested');
58
+ }
59
+ // Standard binary search for the greatest tick < requested tick
60
+ let left = 0;
61
+ let right = this._count - 1;
62
+ let resultLogicalIndex = -1;
63
+ while (left <= right) {
64
+ const mid = (left + right) >>> 1; // floor((left + right) / 2)
65
+ const midTick = this._ticks[this.indexAt(mid)];
66
+ if (midTick < tick) {
67
+ // Candidate: move right to find a closer one
68
+ resultLogicalIndex = mid;
69
+ left = mid + 1;
70
+ }
71
+ else {
72
+ // midTick >= tick, we need smaller ticks
73
+ right = mid - 1;
74
+ }
75
+ }
76
+ if (resultLogicalIndex === -1) {
77
+ throw new Error('No snapshot with tick less than requested');
78
+ }
79
+ const idx = this.indexAt(resultLogicalIndex);
80
+ return this._snapshots[idx];
81
+ }
82
+ /**
83
+ * Remove all snapshots with tick >= given tick.
84
+ * After this call you can safely write new snapshots starting from that tick.
85
+ */
86
+ rollback(tick) {
87
+ if (this._count === 0) {
88
+ this._lastTick = -Infinity;
89
+ return;
90
+ }
91
+ // Find first logical index where tick >= given one
92
+ let left = 0;
93
+ let right = this._count - 1;
94
+ let firstToDrop = this._count; // default: nothing to drop
95
+ while (left <= right) {
96
+ const mid = (left + right) >>> 1;
97
+ const midTick = this._ticks[this.indexAt(mid)];
98
+ if (midTick >= tick) {
99
+ firstToDrop = mid;
100
+ right = mid - 1;
101
+ }
102
+ else {
103
+ left = mid + 1;
104
+ }
105
+ }
106
+ // Keep elements [0, firstToDrop)
107
+ this._count = firstToDrop;
108
+ if (this._count === 0) {
109
+ this._lastTick = -Infinity;
110
+ }
111
+ else {
112
+ this._lastTick = this._ticks[this.indexAt(this._count - 1)];
113
+ }
114
+ }
115
+ // Convert logical index [0..count) to physical index in ring buffer
116
+ indexAt(logicalIndex) {
117
+ // logicalIndex 0 corresponds to head
118
+ const idx = this._head + logicalIndex;
119
+ return idx >= this._maxSize ? idx - this._maxSize : idx;
120
+ }
121
+ }
@@ -0,0 +1,30 @@
1
+ interface Transform2dCursorLike {
2
+ positionX: number;
3
+ positionY: number;
4
+ rotation: number;
5
+ prevPositionX: number;
6
+ prevPositionY: number;
7
+ prevRotation: number;
8
+ }
9
+ export declare const interpolateTransform2dToRef: (prevPositionX: number, prevPositionY: number, positionX: number, positionY: number, prevRotation: number, rotation: number, interpolationFactor: number, ref: {
10
+ x: number;
11
+ y: number;
12
+ rotation: number;
13
+ }, teleportThresholdSquared?: number) => void;
14
+ export declare const interpolateTransform2d: (prevPositionX: number, prevPositionY: number, positionX: number, positionY: number, prevRotation: number, rotation: number, interpolationFactor: number) => {
15
+ readonly x: number;
16
+ readonly y: number;
17
+ readonly rotation: number;
18
+ };
19
+ export declare const interpolateTransform2dCursor: (cursor: Transform2dCursorLike, interpolationFactor: number) => {
20
+ readonly x: number;
21
+ readonly y: number;
22
+ readonly rotation: number;
23
+ };
24
+ export declare const interpolateTransform2dCursorToRef: (cursor: Transform2dCursorLike, interpolationFactor: number, ref: {
25
+ x: number;
26
+ y: number;
27
+ rotation: number;
28
+ }) => void;
29
+ export {};
30
+ //# sourceMappingURL=transform2d-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform2d-utils.d.ts","sourceRoot":"","sources":["../../src/lib/transform2d-utils.ts"],"names":[],"mappings":"AAMA,UAAU,qBAAqB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,2BAA2B,GACtC,eAAe,MAAM,EACrB,eAAe,MAAM,EACrB,WAAW,MAAM,EACjB,WAAW,MAAM,EACjB,cAAc,MAAM,EACpB,UAAU,MAAM,EAChB,qBAAqB,MAAM,EAC3B,KAAK;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC/C,iCAAkD,KACjD,IAcF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,eAAe,MAAM,EACrB,eAAe,MAAM,EACrB,WAAW,MAAM,EACjB,WAAW,MAAM,EACjB,cAAc,MAAM,EACpB,UAAU,MAAM,EAChB,qBAAqB,MAAM,KAC1B;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAarE,CAAA;AAED,eAAO,MAAM,4BAA4B,GACvC,QAAQ,qBAAqB,EAC7B,qBAAqB,MAAM,KAC1B;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAUrE,CAAA;AAED,eAAO,MAAM,iCAAiC,GAC5C,QAAQ,qBAAqB,EAC7B,qBAAqB,MAAM,EAC3B,KAAK;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KAC9C,IAWF,CAAA"}
@@ -0,0 +1,28 @@
1
+ import { MathOps } from '@lagless/math';
2
+ const INTERPOLATION_RESULT_BUFFER = { x: 0, y: 0, rotation: 0 };
3
+ const BASE_TELEPORT_THRESHOLD = 300;
4
+ export const interpolateTransform2dToRef = (prevPositionX, prevPositionY, positionX, positionY, prevRotation, rotation, interpolationFactor, ref, teleportThresholdSquared = BASE_TELEPORT_THRESHOLD) => {
5
+ const dx = positionX - prevPositionX;
6
+ const dy = positionY - prevPositionY;
7
+ const distanceSquared = dx * dx + dy * dy;
8
+ if (distanceSquared >= teleportThresholdSquared * teleportThresholdSquared) {
9
+ ref.x = positionX;
10
+ ref.y = positionY;
11
+ ref.rotation = -rotation;
12
+ }
13
+ else {
14
+ ref.x = prevPositionX + dx * interpolationFactor;
15
+ ref.y = -(prevPositionY + dy * interpolationFactor);
16
+ ref.rotation = -MathOps.lerpAngle(prevRotation, rotation, interpolationFactor);
17
+ }
18
+ };
19
+ export const interpolateTransform2d = (prevPositionX, prevPositionY, positionX, positionY, prevRotation, rotation, interpolationFactor) => {
20
+ interpolateTransform2dToRef(prevPositionX, prevPositionY, positionX, positionY, prevRotation, rotation, interpolationFactor, INTERPOLATION_RESULT_BUFFER);
21
+ return INTERPOLATION_RESULT_BUFFER;
22
+ };
23
+ export const interpolateTransform2dCursor = (cursor, interpolationFactor) => {
24
+ return interpolateTransform2d(cursor.prevPositionX, cursor.prevPositionY, cursor.positionX, cursor.positionY, cursor.prevRotation, cursor.rotation, interpolationFactor);
25
+ };
26
+ export const interpolateTransform2dCursorToRef = (cursor, interpolationFactor, ref) => {
27
+ interpolateTransform2dToRef(cursor.prevPositionX, cursor.prevPositionY, cursor.positionX, cursor.positionY, cursor.prevRotation, cursor.rotation, interpolationFactor, ref);
28
+ };
@@ -0,0 +1,33 @@
1
+ export declare class UUID {
2
+ private readonly _bytes;
3
+ private _stringCache;
4
+ private constructor();
5
+ /**
6
+ * Generate a standard random (v4) UUID.
7
+ */
8
+ static generate(): UUID;
9
+ /**
10
+ * Generate a "Masked" UUID.
11
+ *
12
+ * It looks like a standard v4 UUID, but the last 4 bytes (32 bits)
13
+ * are a checksum of the first 12 bytes.
14
+ *
15
+ * Entropy: 90 bits (vs 122 in standard v4).
16
+ * False positive rate: 1 in ~4.3 billion.
17
+ */
18
+ static generateMasked(): UUID;
19
+ /**
20
+ * Check if a Uint8Array (16 bytes) represents a Masked UUID.
21
+ */
22
+ static isMaskedUint8(bytes: Uint8Array): boolean;
23
+ /**
24
+ * Check if a UUID string is a Masked UUID.
25
+ * Returns false if string is invalid or not masked.
26
+ */
27
+ static isMaskedString(uuidStr: string): boolean;
28
+ static fromString(uuidStr: string): UUID;
29
+ static fromUint8(uuidUint8: Uint8Array): UUID;
30
+ asString(): string;
31
+ asUint8(): Uint8Array;
32
+ }
33
+ //# sourceMappingURL=uuid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../src/lib/uuid.ts"],"names":[],"mappings":"AAqHA,qBAAa,IAAI;IACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,YAAY,CAAuB;IAE3C,OAAO;IAIP;;OAEG;WACW,QAAQ,IAAI,IAAI;IAY9B;;;;;;;;OAQG;WACW,cAAc,IAAI,IAAI;IAoBpC;;OAEG;WACW,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAavD;;;OAGG;WACW,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;WAWxC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;WAKjC,SAAS,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;IAQ7C,QAAQ,IAAI,MAAM;IAOlB,OAAO,IAAI,UAAU;CAG7B"}