@al8b/time 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +23 -0
  2. package/dist/constants.d.mts +6 -0
  3. package/dist/constants.d.ts +6 -0
  4. package/dist/constants.js +34 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/constants.mjs +8 -0
  7. package/dist/constants.mjs.map +1 -0
  8. package/dist/core/index.d.mts +2 -0
  9. package/dist/core/index.d.ts +2 -0
  10. package/dist/core/index.js +522 -0
  11. package/dist/core/index.js.map +1 -0
  12. package/dist/core/index.mjs +497 -0
  13. package/dist/core/index.mjs.map +1 -0
  14. package/dist/core/machine.d.mts +101 -0
  15. package/dist/core/machine.d.ts +101 -0
  16. package/dist/core/machine.js +520 -0
  17. package/dist/core/machine.js.map +1 -0
  18. package/dist/core/machine.mjs +497 -0
  19. package/dist/core/machine.mjs.map +1 -0
  20. package/dist/index.d.mts +4 -0
  21. package/dist/index.d.ts +4 -0
  22. package/dist/index.js +526 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/index.mjs +499 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/playback/index.d.mts +2 -0
  27. package/dist/playback/index.d.ts +2 -0
  28. package/dist/playback/index.js +172 -0
  29. package/dist/playback/index.js.map +1 -0
  30. package/dist/playback/index.mjs +147 -0
  31. package/dist/playback/index.mjs.map +1 -0
  32. package/dist/playback/player.d.mts +41 -0
  33. package/dist/playback/player.d.ts +41 -0
  34. package/dist/playback/player.js +172 -0
  35. package/dist/playback/player.js.map +1 -0
  36. package/dist/playback/player.mjs +147 -0
  37. package/dist/playback/player.mjs.map +1 -0
  38. package/dist/recording/index.d.mts +2 -0
  39. package/dist/recording/index.d.ts +2 -0
  40. package/dist/recording/index.js +149 -0
  41. package/dist/recording/index.js.map +1 -0
  42. package/dist/recording/index.mjs +124 -0
  43. package/dist/recording/index.mjs.map +1 -0
  44. package/dist/recording/recorder.d.mts +41 -0
  45. package/dist/recording/recorder.d.ts +41 -0
  46. package/dist/recording/recorder.js +149 -0
  47. package/dist/recording/recorder.js.map +1 -0
  48. package/dist/recording/recorder.mjs +124 -0
  49. package/dist/recording/recorder.mjs.map +1 -0
  50. package/dist/types/index.d.mts +1 -0
  51. package/dist/types/index.d.ts +1 -0
  52. package/dist/types/index.js +19 -0
  53. package/dist/types/index.js.map +1 -0
  54. package/dist/types/index.mjs +1 -0
  55. package/dist/types/index.mjs.map +1 -0
  56. package/dist/types/state.d.mts +33 -0
  57. package/dist/types/state.d.ts +33 -0
  58. package/dist/types/state.js +19 -0
  59. package/dist/types/state.js.map +1 -0
  60. package/dist/types/state.mjs +1 -0
  61. package/dist/types/state.mjs.map +1 -0
  62. package/dist/utils.d.mts +9 -0
  63. package/dist/utils.d.ts +9 -0
  64. package/dist/utils.js +60 -0
  65. package/dist/utils.js.map +1 -0
  66. package/dist/utils.mjs +37 -0
  67. package/dist/utils.mjs.map +1 -0
  68. package/package.json +37 -0
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/recording/recorder.ts
22
+ var recorder_exports = {};
23
+ __export(recorder_exports, {
24
+ StateRecorder: () => StateRecorder
25
+ });
26
+ module.exports = __toCommonJS(recorder_exports);
27
+
28
+ // src/constants.ts
29
+ var DEFAULT_RECORD_BUFFER_FRAMES = 60 * 30;
30
+ var DEFAULT_LOOP_BUFFER_FRAMES = 60 * 4;
31
+
32
+ // src/utils.ts
33
+ function deepCopy(value, excluded) {
34
+ if (value == null) {
35
+ return value;
36
+ }
37
+ if (excluded && excluded.includes(value)) {
38
+ return null;
39
+ }
40
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
41
+ return value;
42
+ }
43
+ if (Array.isArray(value)) {
44
+ const result = [];
45
+ for (let i = 0; i < value.length; i++) {
46
+ result[i] = deepCopy(value[i], excluded);
47
+ }
48
+ return result;
49
+ }
50
+ if (typeof value === "object") {
51
+ const result = {};
52
+ for (const key in value) {
53
+ if (Object.hasOwn(value, key)) {
54
+ result[key] = deepCopy(value[key], excluded);
55
+ }
56
+ }
57
+ return result;
58
+ }
59
+ return excluded ? null : value;
60
+ }
61
+ __name(deepCopy, "deepCopy");
62
+
63
+ // src/recording/recorder.ts
64
+ var StateRecorder = class {
65
+ static {
66
+ __name(this, "StateRecorder");
67
+ }
68
+ history = [];
69
+ recordIndex = 0;
70
+ recordLength = 0;
71
+ maxLength;
72
+ excluded = [];
73
+ constructor(maxLength = DEFAULT_RECORD_BUFFER_FRAMES) {
74
+ this.maxLength = maxLength;
75
+ }
76
+ /**
77
+ * Set objects to exclude from serialization
78
+ */
79
+ setExcluded(excluded) {
80
+ this.excluded = excluded;
81
+ }
82
+ /**
83
+ * Record a state snapshot
84
+ */
85
+ record(state) {
86
+ const snapshot = this.makeStorableState(state);
87
+ this.history[this.recordIndex++] = snapshot;
88
+ this.recordLength = Math.min(this.recordLength + 1, this.maxLength);
89
+ if (this.recordIndex >= this.maxLength) {
90
+ this.recordIndex = 0;
91
+ }
92
+ }
93
+ /**
94
+ * Get state at specific position (0 = most recent)
95
+ */
96
+ getState(position) {
97
+ if (position >= this.recordLength) {
98
+ return null;
99
+ }
100
+ const index = (this.recordIndex - position - 1 + this.maxLength) % this.maxLength;
101
+ return this.history[index];
102
+ }
103
+ /**
104
+ * Get current record length
105
+ */
106
+ getLength() {
107
+ return this.recordLength;
108
+ }
109
+ /**
110
+ * Get maximum record length
111
+ */
112
+ getMaxLength() {
113
+ return this.maxLength;
114
+ }
115
+ /**
116
+ * Clear all recorded history
117
+ */
118
+ clear() {
119
+ this.history = [];
120
+ this.recordIndex = 0;
121
+ this.recordLength = 0;
122
+ }
123
+ /**
124
+ * Trim history to specific position
125
+ */
126
+ trimTo(position) {
127
+ if (position >= this.recordLength) {
128
+ return;
129
+ }
130
+ const histo = [];
131
+ const start = this.recordLength;
132
+ const end = position + 1;
133
+ for (let i = start; i >= end; i--) {
134
+ const index = (this.recordIndex - i + this.maxLength) % this.maxLength;
135
+ histo.push(this.history[index]);
136
+ }
137
+ this.history = histo;
138
+ this.recordIndex = this.history.length;
139
+ this.recordLength = this.history.length;
140
+ }
141
+ makeStorableState(value) {
142
+ return deepCopy(value, this.excluded);
143
+ }
144
+ };
145
+ // Annotate the CommonJS export names for ESM import in node:
146
+ 0 && (module.exports = {
147
+ StateRecorder
148
+ });
149
+ //# sourceMappingURL=recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/recording/recorder.ts","../../src/constants.ts","../../src/utils.ts"],"sourcesContent":["/**\n * StateRecorder - Records game state history\n *\n * Responsibilities:\n * - Capture state snapshots\n * - Manage circular buffer\n * - Exclude non-serializable objects\n */\nimport { DEFAULT_RECORD_BUFFER_FRAMES } from \"../constants\";\nimport { deepCopy } from \"../utils\";\n\nimport type { StateSnapshot } from \"../types\";\n\nexport class StateRecorder {\n\tprivate history: StateSnapshot[] = [];\n\tprivate recordIndex = 0;\n\tprivate recordLength = 0;\n\tprivate maxLength: number;\n\tprivate excluded: any[] = [];\n\n\tconstructor(maxLength = DEFAULT_RECORD_BUFFER_FRAMES) {\n\t\tthis.maxLength = maxLength;\n\t}\n\n\t/**\n\t * Set objects to exclude from serialization\n\t */\n\tsetExcluded(excluded: any[]): void {\n\t\tthis.excluded = excluded;\n\t}\n\n\t/**\n\t * Record a state snapshot\n\t */\n\trecord(state: any): void {\n\t\tconst snapshot = this.makeStorableState(state);\n\t\tthis.history[this.recordIndex++] = snapshot;\n\t\tthis.recordLength = Math.min(this.recordLength + 1, this.maxLength);\n\n\t\tif (this.recordIndex >= this.maxLength) {\n\t\t\tthis.recordIndex = 0;\n\t\t}\n\t}\n\n\t/**\n\t * Get state at specific position (0 = most recent)\n\t */\n\tgetState(position: number): StateSnapshot | null {\n\t\tif (position >= this.recordLength) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst index = (this.recordIndex - position - 1 + this.maxLength) % this.maxLength;\n\t\treturn this.history[index];\n\t}\n\n\t/**\n\t * Get current record length\n\t */\n\tgetLength(): number {\n\t\treturn this.recordLength;\n\t}\n\n\t/**\n\t * Get maximum record length\n\t */\n\tgetMaxLength(): number {\n\t\treturn this.maxLength;\n\t}\n\n\t/**\n\t * Clear all recorded history\n\t */\n\tclear(): void {\n\t\tthis.history = [];\n\t\tthis.recordIndex = 0;\n\t\tthis.recordLength = 0;\n\t}\n\n\t/**\n\t * Trim history to specific position\n\t */\n\ttrimTo(position: number): void {\n\t\tif (position >= this.recordLength) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst histo: StateSnapshot[] = [];\n\t\tconst start = this.recordLength;\n\t\tconst end = position + 1;\n\n\t\tfor (let i = start; i >= end; i--) {\n\t\t\tconst index = (this.recordIndex - i + this.maxLength) % this.maxLength;\n\t\t\thisto.push(this.history[index]);\n\t\t}\n\n\t\tthis.history = histo;\n\t\tthis.recordIndex = this.history.length;\n\t\tthis.recordLength = this.history.length;\n\t}\n\n\tprivate makeStorableState(value: any): any {\n\t\treturn deepCopy(value, this.excluded);\n\t}\n}\n","/** Default recording buffer: 30 seconds at 60fps (1800 frames) */\nexport const DEFAULT_RECORD_BUFFER_FRAMES = 60 * 30;\n\n/** Default loop playback buffer: 4 seconds at 60fps (240 frames) */\nexport const DEFAULT_LOOP_BUFFER_FRAMES = 60 * 4;\n","/**\n * Deep copy a value, optionally skipping excluded references.\n *\n * @param value - The value to deep copy\n * @param excluded - Optional array of object references to skip (replaced with null)\n */\nexport function deepCopy(value: any, excluded?: any[]): any {\n\tif (value == null) {\n\t\treturn value;\n\t}\n\n\tif (excluded && excluded.includes(value)) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn value;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tconst result: any[] = [];\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tresult[i] = deepCopy(value[i], excluded);\n\t\t}\n\t\treturn result;\n\t}\n\n\tif (typeof value === \"object\") {\n\t\tconst result: any = {};\n\t\tfor (const key in value) {\n\t\t\tif (Object.hasOwn(value, key)) {\n\t\t\t\tresult[key] = deepCopy(value[key], excluded);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t// Non-serializable types: return null when filtering, passthrough otherwise\n\treturn excluded ? null : value;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;ACCO,IAAMA,+BAA+B,KAAK;AAG1C,IAAMC,6BAA6B,KAAK;;;ACExC,SAASC,SAASC,OAAYC,UAAgB;AACpD,MAAID,SAAS,MAAM;AAClB,WAAOA;EACR;AAEA,MAAIC,YAAYA,SAASC,SAASF,KAAAA,GAAQ;AACzC,WAAO;EACR;AAEA,MAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,YAAY,OAAOA,UAAU,WAAW;AACzF,WAAOA;EACR;AAEA,MAAIG,MAAMC,QAAQJ,KAAAA,GAAQ;AACzB,UAAMK,SAAgB,CAAA;AACtB,aAASC,IAAI,GAAGA,IAAIN,MAAMO,QAAQD,KAAK;AACtCD,aAAOC,CAAAA,IAAKP,SAASC,MAAMM,CAAAA,GAAIL,QAAAA;IAChC;AACA,WAAOI;EACR;AAEA,MAAI,OAAOL,UAAU,UAAU;AAC9B,UAAMK,SAAc,CAAC;AACrB,eAAWG,OAAOR,OAAO;AACxB,UAAIS,OAAOC,OAAOV,OAAOQ,GAAAA,GAAM;AAC9BH,eAAOG,GAAAA,IAAOT,SAASC,MAAMQ,GAAAA,GAAMP,QAAAA;MACpC;IACD;AACA,WAAOI;EACR;AAGA,SAAOJ,WAAW,OAAOD;AAC1B;AAjCgBD;;;AFOT,IAAMY,gBAAN,MAAMA;EAbb,OAaaA;;;EACJC,UAA2B,CAAA;EAC3BC,cAAc;EACdC,eAAe;EACfC;EACAC,WAAkB,CAAA;EAE1B,YAAYD,YAAYE,8BAA8B;AACrD,SAAKF,YAAYA;EAClB;;;;EAKAG,YAAYF,UAAuB;AAClC,SAAKA,WAAWA;EACjB;;;;EAKAG,OAAOC,OAAkB;AACxB,UAAMC,WAAW,KAAKC,kBAAkBF,KAAAA;AACxC,SAAKR,QAAQ,KAAKC,aAAW,IAAMQ;AACnC,SAAKP,eAAeS,KAAKC,IAAI,KAAKV,eAAe,GAAG,KAAKC,SAAS;AAElE,QAAI,KAAKF,eAAe,KAAKE,WAAW;AACvC,WAAKF,cAAc;IACpB;EACD;;;;EAKAY,SAASC,UAAwC;AAChD,QAAIA,YAAY,KAAKZ,cAAc;AAClC,aAAO;IACR;AAEA,UAAMa,SAAS,KAAKd,cAAca,WAAW,IAAI,KAAKX,aAAa,KAAKA;AACxE,WAAO,KAAKH,QAAQe,KAAAA;EACrB;;;;EAKAC,YAAoB;AACnB,WAAO,KAAKd;EACb;;;;EAKAe,eAAuB;AACtB,WAAO,KAAKd;EACb;;;;EAKAe,QAAc;AACb,SAAKlB,UAAU,CAAA;AACf,SAAKC,cAAc;AACnB,SAAKC,eAAe;EACrB;;;;EAKAiB,OAAOL,UAAwB;AAC9B,QAAIA,YAAY,KAAKZ,cAAc;AAClC;IACD;AAEA,UAAMkB,QAAyB,CAAA;AAC/B,UAAMC,QAAQ,KAAKnB;AACnB,UAAMoB,MAAMR,WAAW;AAEvB,aAASS,IAAIF,OAAOE,KAAKD,KAAKC,KAAK;AAClC,YAAMR,SAAS,KAAKd,cAAcsB,IAAI,KAAKpB,aAAa,KAAKA;AAC7DiB,YAAMI,KAAK,KAAKxB,QAAQe,KAAAA,CAAM;IAC/B;AAEA,SAAKf,UAAUoB;AACf,SAAKnB,cAAc,KAAKD,QAAQyB;AAChC,SAAKvB,eAAe,KAAKF,QAAQyB;EAClC;EAEQf,kBAAkBgB,OAAiB;AAC1C,WAAOC,SAASD,OAAO,KAAKtB,QAAQ;EACrC;AACD;","names":["DEFAULT_RECORD_BUFFER_FRAMES","DEFAULT_LOOP_BUFFER_FRAMES","deepCopy","value","excluded","includes","Array","isArray","result","i","length","key","Object","hasOwn","StateRecorder","history","recordIndex","recordLength","maxLength","excluded","DEFAULT_RECORD_BUFFER_FRAMES","setExcluded","record","state","snapshot","makeStorableState","Math","min","getState","position","index","getLength","getMaxLength","clear","trimTo","histo","start","end","i","push","length","value","deepCopy"]}
@@ -0,0 +1,124 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/constants.ts
5
+ var DEFAULT_RECORD_BUFFER_FRAMES = 60 * 30;
6
+ var DEFAULT_LOOP_BUFFER_FRAMES = 60 * 4;
7
+
8
+ // src/utils.ts
9
+ function deepCopy(value, excluded) {
10
+ if (value == null) {
11
+ return value;
12
+ }
13
+ if (excluded && excluded.includes(value)) {
14
+ return null;
15
+ }
16
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
17
+ return value;
18
+ }
19
+ if (Array.isArray(value)) {
20
+ const result = [];
21
+ for (let i = 0; i < value.length; i++) {
22
+ result[i] = deepCopy(value[i], excluded);
23
+ }
24
+ return result;
25
+ }
26
+ if (typeof value === "object") {
27
+ const result = {};
28
+ for (const key in value) {
29
+ if (Object.hasOwn(value, key)) {
30
+ result[key] = deepCopy(value[key], excluded);
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ return excluded ? null : value;
36
+ }
37
+ __name(deepCopy, "deepCopy");
38
+
39
+ // src/recording/recorder.ts
40
+ var StateRecorder = class {
41
+ static {
42
+ __name(this, "StateRecorder");
43
+ }
44
+ history = [];
45
+ recordIndex = 0;
46
+ recordLength = 0;
47
+ maxLength;
48
+ excluded = [];
49
+ constructor(maxLength = DEFAULT_RECORD_BUFFER_FRAMES) {
50
+ this.maxLength = maxLength;
51
+ }
52
+ /**
53
+ * Set objects to exclude from serialization
54
+ */
55
+ setExcluded(excluded) {
56
+ this.excluded = excluded;
57
+ }
58
+ /**
59
+ * Record a state snapshot
60
+ */
61
+ record(state) {
62
+ const snapshot = this.makeStorableState(state);
63
+ this.history[this.recordIndex++] = snapshot;
64
+ this.recordLength = Math.min(this.recordLength + 1, this.maxLength);
65
+ if (this.recordIndex >= this.maxLength) {
66
+ this.recordIndex = 0;
67
+ }
68
+ }
69
+ /**
70
+ * Get state at specific position (0 = most recent)
71
+ */
72
+ getState(position) {
73
+ if (position >= this.recordLength) {
74
+ return null;
75
+ }
76
+ const index = (this.recordIndex - position - 1 + this.maxLength) % this.maxLength;
77
+ return this.history[index];
78
+ }
79
+ /**
80
+ * Get current record length
81
+ */
82
+ getLength() {
83
+ return this.recordLength;
84
+ }
85
+ /**
86
+ * Get maximum record length
87
+ */
88
+ getMaxLength() {
89
+ return this.maxLength;
90
+ }
91
+ /**
92
+ * Clear all recorded history
93
+ */
94
+ clear() {
95
+ this.history = [];
96
+ this.recordIndex = 0;
97
+ this.recordLength = 0;
98
+ }
99
+ /**
100
+ * Trim history to specific position
101
+ */
102
+ trimTo(position) {
103
+ if (position >= this.recordLength) {
104
+ return;
105
+ }
106
+ const histo = [];
107
+ const start = this.recordLength;
108
+ const end = position + 1;
109
+ for (let i = start; i >= end; i--) {
110
+ const index = (this.recordIndex - i + this.maxLength) % this.maxLength;
111
+ histo.push(this.history[index]);
112
+ }
113
+ this.history = histo;
114
+ this.recordIndex = this.history.length;
115
+ this.recordLength = this.history.length;
116
+ }
117
+ makeStorableState(value) {
118
+ return deepCopy(value, this.excluded);
119
+ }
120
+ };
121
+ export {
122
+ StateRecorder
123
+ };
124
+ //# sourceMappingURL=recorder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/recording/recorder.ts"],"sourcesContent":["/** Default recording buffer: 30 seconds at 60fps (1800 frames) */\nexport const DEFAULT_RECORD_BUFFER_FRAMES = 60 * 30;\n\n/** Default loop playback buffer: 4 seconds at 60fps (240 frames) */\nexport const DEFAULT_LOOP_BUFFER_FRAMES = 60 * 4;\n","/**\n * Deep copy a value, optionally skipping excluded references.\n *\n * @param value - The value to deep copy\n * @param excluded - Optional array of object references to skip (replaced with null)\n */\nexport function deepCopy(value: any, excluded?: any[]): any {\n\tif (value == null) {\n\t\treturn value;\n\t}\n\n\tif (excluded && excluded.includes(value)) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn value;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tconst result: any[] = [];\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tresult[i] = deepCopy(value[i], excluded);\n\t\t}\n\t\treturn result;\n\t}\n\n\tif (typeof value === \"object\") {\n\t\tconst result: any = {};\n\t\tfor (const key in value) {\n\t\t\tif (Object.hasOwn(value, key)) {\n\t\t\t\tresult[key] = deepCopy(value[key], excluded);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t// Non-serializable types: return null when filtering, passthrough otherwise\n\treturn excluded ? null : value;\n}\n","/**\n * StateRecorder - Records game state history\n *\n * Responsibilities:\n * - Capture state snapshots\n * - Manage circular buffer\n * - Exclude non-serializable objects\n */\nimport { DEFAULT_RECORD_BUFFER_FRAMES } from \"../constants\";\nimport { deepCopy } from \"../utils\";\n\nimport type { StateSnapshot } from \"../types\";\n\nexport class StateRecorder {\n\tprivate history: StateSnapshot[] = [];\n\tprivate recordIndex = 0;\n\tprivate recordLength = 0;\n\tprivate maxLength: number;\n\tprivate excluded: any[] = [];\n\n\tconstructor(maxLength = DEFAULT_RECORD_BUFFER_FRAMES) {\n\t\tthis.maxLength = maxLength;\n\t}\n\n\t/**\n\t * Set objects to exclude from serialization\n\t */\n\tsetExcluded(excluded: any[]): void {\n\t\tthis.excluded = excluded;\n\t}\n\n\t/**\n\t * Record a state snapshot\n\t */\n\trecord(state: any): void {\n\t\tconst snapshot = this.makeStorableState(state);\n\t\tthis.history[this.recordIndex++] = snapshot;\n\t\tthis.recordLength = Math.min(this.recordLength + 1, this.maxLength);\n\n\t\tif (this.recordIndex >= this.maxLength) {\n\t\t\tthis.recordIndex = 0;\n\t\t}\n\t}\n\n\t/**\n\t * Get state at specific position (0 = most recent)\n\t */\n\tgetState(position: number): StateSnapshot | null {\n\t\tif (position >= this.recordLength) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst index = (this.recordIndex - position - 1 + this.maxLength) % this.maxLength;\n\t\treturn this.history[index];\n\t}\n\n\t/**\n\t * Get current record length\n\t */\n\tgetLength(): number {\n\t\treturn this.recordLength;\n\t}\n\n\t/**\n\t * Get maximum record length\n\t */\n\tgetMaxLength(): number {\n\t\treturn this.maxLength;\n\t}\n\n\t/**\n\t * Clear all recorded history\n\t */\n\tclear(): void {\n\t\tthis.history = [];\n\t\tthis.recordIndex = 0;\n\t\tthis.recordLength = 0;\n\t}\n\n\t/**\n\t * Trim history to specific position\n\t */\n\ttrimTo(position: number): void {\n\t\tif (position >= this.recordLength) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst histo: StateSnapshot[] = [];\n\t\tconst start = this.recordLength;\n\t\tconst end = position + 1;\n\n\t\tfor (let i = start; i >= end; i--) {\n\t\t\tconst index = (this.recordIndex - i + this.maxLength) % this.maxLength;\n\t\t\thisto.push(this.history[index]);\n\t\t}\n\n\t\tthis.history = histo;\n\t\tthis.recordIndex = this.history.length;\n\t\tthis.recordLength = this.history.length;\n\t}\n\n\tprivate makeStorableState(value: any): any {\n\t\treturn deepCopy(value, this.excluded);\n\t}\n}\n"],"mappings":";;;;AACO,IAAMA,+BAA+B,KAAK;AAG1C,IAAMC,6BAA6B,KAAK;;;ACExC,SAASC,SAASC,OAAYC,UAAgB;AACpD,MAAID,SAAS,MAAM;AAClB,WAAOA;EACR;AAEA,MAAIC,YAAYA,SAASC,SAASF,KAAAA,GAAQ;AACzC,WAAO;EACR;AAEA,MAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,YAAY,OAAOA,UAAU,WAAW;AACzF,WAAOA;EACR;AAEA,MAAIG,MAAMC,QAAQJ,KAAAA,GAAQ;AACzB,UAAMK,SAAgB,CAAA;AACtB,aAASC,IAAI,GAAGA,IAAIN,MAAMO,QAAQD,KAAK;AACtCD,aAAOC,CAAAA,IAAKP,SAASC,MAAMM,CAAAA,GAAIL,QAAAA;IAChC;AACA,WAAOI;EACR;AAEA,MAAI,OAAOL,UAAU,UAAU;AAC9B,UAAMK,SAAc,CAAC;AACrB,eAAWG,OAAOR,OAAO;AACxB,UAAIS,OAAOC,OAAOV,OAAOQ,GAAAA,GAAM;AAC9BH,eAAOG,GAAAA,IAAOT,SAASC,MAAMQ,GAAAA,GAAMP,QAAAA;MACpC;IACD;AACA,WAAOI;EACR;AAGA,SAAOJ,WAAW,OAAOD;AAC1B;AAjCgBD;;;ACOT,IAAMY,gBAAN,MAAMA;EAbb,OAaaA;;;EACJC,UAA2B,CAAA;EAC3BC,cAAc;EACdC,eAAe;EACfC;EACAC,WAAkB,CAAA;EAE1B,YAAYD,YAAYE,8BAA8B;AACrD,SAAKF,YAAYA;EAClB;;;;EAKAG,YAAYF,UAAuB;AAClC,SAAKA,WAAWA;EACjB;;;;EAKAG,OAAOC,OAAkB;AACxB,UAAMC,WAAW,KAAKC,kBAAkBF,KAAAA;AACxC,SAAKR,QAAQ,KAAKC,aAAW,IAAMQ;AACnC,SAAKP,eAAeS,KAAKC,IAAI,KAAKV,eAAe,GAAG,KAAKC,SAAS;AAElE,QAAI,KAAKF,eAAe,KAAKE,WAAW;AACvC,WAAKF,cAAc;IACpB;EACD;;;;EAKAY,SAASC,UAAwC;AAChD,QAAIA,YAAY,KAAKZ,cAAc;AAClC,aAAO;IACR;AAEA,UAAMa,SAAS,KAAKd,cAAca,WAAW,IAAI,KAAKX,aAAa,KAAKA;AACxE,WAAO,KAAKH,QAAQe,KAAAA;EACrB;;;;EAKAC,YAAoB;AACnB,WAAO,KAAKd;EACb;;;;EAKAe,eAAuB;AACtB,WAAO,KAAKd;EACb;;;;EAKAe,QAAc;AACb,SAAKlB,UAAU,CAAA;AACf,SAAKC,cAAc;AACnB,SAAKC,eAAe;EACrB;;;;EAKAiB,OAAOL,UAAwB;AAC9B,QAAIA,YAAY,KAAKZ,cAAc;AAClC;IACD;AAEA,UAAMkB,QAAyB,CAAA;AAC/B,UAAMC,QAAQ,KAAKnB;AACnB,UAAMoB,MAAMR,WAAW;AAEvB,aAASS,IAAIF,OAAOE,KAAKD,KAAKC,KAAK;AAClC,YAAMR,SAAS,KAAKd,cAAcsB,IAAI,KAAKpB,aAAa,KAAKA;AAC7DiB,YAAMI,KAAK,KAAKxB,QAAQe,KAAAA,CAAM;IAC/B;AAEA,SAAKf,UAAUoB;AACf,SAAKnB,cAAc,KAAKD,QAAQyB;AAChC,SAAKvB,eAAe,KAAKF,QAAQyB;EAClC;EAEQf,kBAAkBgB,OAAiB;AAC1C,WAAOC,SAASD,OAAO,KAAKtB,QAAQ;EACrC;AACD;","names":["DEFAULT_RECORD_BUFFER_FRAMES","DEFAULT_LOOP_BUFFER_FRAMES","deepCopy","value","excluded","includes","Array","isArray","result","i","length","key","Object","hasOwn","StateRecorder","history","recordIndex","recordLength","maxLength","excluded","DEFAULT_RECORD_BUFFER_FRAMES","setExcluded","record","state","snapshot","makeStorableState","Math","min","getState","position","index","getLength","getMaxLength","clear","trimTo","histo","start","end","i","push","length","value","deepCopy"]}
@@ -0,0 +1 @@
1
+ export { StateSnapshot, TimeMachineCommand, TimeMachineMessage, TimeMachineStatus } from './state.mjs';
@@ -0,0 +1 @@
1
+ export { StateSnapshot, TimeMachineCommand, TimeMachineMessage, TimeMachineStatus } from './state.js';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types/index.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Type definitions for @al8b/time\n */\n\nexport type {\n\tStateSnapshot,\n\tTimeMachineCommand,\n\tTimeMachineMessage,\n\tTimeMachineStatus,\n} from \"./state\";\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;;","names":[]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * State types for time machine
3
+ */
4
+ /**
5
+ * Serialized game state snapshot
6
+ */
7
+ interface StateSnapshot {
8
+ [key: string]: any;
9
+ }
10
+ /**
11
+ * Time machine command types
12
+ */
13
+ type TimeMachineCommand = "start_recording" | "stop_recording" | "step_backward" | "step_forward" | "replay_position" | "start_looping" | "stop_looping";
14
+ /**
15
+ * Message format for time machine control
16
+ */
17
+ interface TimeMachineMessage {
18
+ name: "time_machine";
19
+ command: TimeMachineCommand;
20
+ position?: number;
21
+ }
22
+ /**
23
+ * Status information for time machine
24
+ */
25
+ interface TimeMachineStatus {
26
+ recording: boolean;
27
+ looping: boolean;
28
+ position: number;
29
+ length: number;
30
+ max: number;
31
+ }
32
+
33
+ export type { StateSnapshot, TimeMachineCommand, TimeMachineMessage, TimeMachineStatus };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * State types for time machine
3
+ */
4
+ /**
5
+ * Serialized game state snapshot
6
+ */
7
+ interface StateSnapshot {
8
+ [key: string]: any;
9
+ }
10
+ /**
11
+ * Time machine command types
12
+ */
13
+ type TimeMachineCommand = "start_recording" | "stop_recording" | "step_backward" | "step_forward" | "replay_position" | "start_looping" | "stop_looping";
14
+ /**
15
+ * Message format for time machine control
16
+ */
17
+ interface TimeMachineMessage {
18
+ name: "time_machine";
19
+ command: TimeMachineCommand;
20
+ position?: number;
21
+ }
22
+ /**
23
+ * Status information for time machine
24
+ */
25
+ interface TimeMachineStatus {
26
+ recording: boolean;
27
+ looping: boolean;
28
+ position: number;
29
+ length: number;
30
+ max: number;
31
+ }
32
+
33
+ export type { StateSnapshot, TimeMachineCommand, TimeMachineMessage, TimeMachineStatus };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types/state.ts
17
+ var state_exports = {};
18
+ module.exports = __toCommonJS(state_exports);
19
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/state.ts"],"sourcesContent":["/**\n * State types for time machine\n */\n\n/**\n * Serialized game state snapshot\n */\nexport interface StateSnapshot {\n\t[key: string]: any;\n}\n\n/**\n * Time machine command types\n */\nexport type TimeMachineCommand =\n\t| \"start_recording\"\n\t| \"stop_recording\"\n\t| \"step_backward\"\n\t| \"step_forward\"\n\t| \"replay_position\"\n\t| \"start_looping\"\n\t| \"stop_looping\";\n\n/**\n * Message format for time machine control\n */\nexport interface TimeMachineMessage {\n\tname: \"time_machine\";\n\tcommand: TimeMachineCommand;\n\tposition?: number;\n}\n\n/**\n * Status information for time machine\n */\nexport interface TimeMachineStatus {\n\trecording: boolean;\n\tlooping: boolean;\n\tposition: number;\n\tlength: number;\n\tmax: number;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;;","names":[]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=state.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Deep copy a value, optionally skipping excluded references.
3
+ *
4
+ * @param value - The value to deep copy
5
+ * @param excluded - Optional array of object references to skip (replaced with null)
6
+ */
7
+ declare function deepCopy(value: any, excluded?: any[]): any;
8
+
9
+ export { deepCopy };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Deep copy a value, optionally skipping excluded references.
3
+ *
4
+ * @param value - The value to deep copy
5
+ * @param excluded - Optional array of object references to skip (replaced with null)
6
+ */
7
+ declare function deepCopy(value: any, excluded?: any[]): any;
8
+
9
+ export { deepCopy };
package/dist/utils.js ADDED
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/utils.ts
22
+ var utils_exports = {};
23
+ __export(utils_exports, {
24
+ deepCopy: () => deepCopy
25
+ });
26
+ module.exports = __toCommonJS(utils_exports);
27
+ function deepCopy(value, excluded) {
28
+ if (value == null) {
29
+ return value;
30
+ }
31
+ if (excluded && excluded.includes(value)) {
32
+ return null;
33
+ }
34
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
35
+ return value;
36
+ }
37
+ if (Array.isArray(value)) {
38
+ const result = [];
39
+ for (let i = 0; i < value.length; i++) {
40
+ result[i] = deepCopy(value[i], excluded);
41
+ }
42
+ return result;
43
+ }
44
+ if (typeof value === "object") {
45
+ const result = {};
46
+ for (const key in value) {
47
+ if (Object.hasOwn(value, key)) {
48
+ result[key] = deepCopy(value[key], excluded);
49
+ }
50
+ }
51
+ return result;
52
+ }
53
+ return excluded ? null : value;
54
+ }
55
+ __name(deepCopy, "deepCopy");
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ deepCopy
59
+ });
60
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["/**\n * Deep copy a value, optionally skipping excluded references.\n *\n * @param value - The value to deep copy\n * @param excluded - Optional array of object references to skip (replaced with null)\n */\nexport function deepCopy(value: any, excluded?: any[]): any {\n\tif (value == null) {\n\t\treturn value;\n\t}\n\n\tif (excluded && excluded.includes(value)) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn value;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tconst result: any[] = [];\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tresult[i] = deepCopy(value[i], excluded);\n\t\t}\n\t\treturn result;\n\t}\n\n\tif (typeof value === \"object\") {\n\t\tconst result: any = {};\n\t\tfor (const key in value) {\n\t\t\tif (Object.hasOwn(value, key)) {\n\t\t\t\tresult[key] = deepCopy(value[key], excluded);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t// Non-serializable types: return null when filtering, passthrough otherwise\n\treturn excluded ? null : value;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAMO,SAASA,SAASC,OAAYC,UAAgB;AACpD,MAAID,SAAS,MAAM;AAClB,WAAOA;EACR;AAEA,MAAIC,YAAYA,SAASC,SAASF,KAAAA,GAAQ;AACzC,WAAO;EACR;AAEA,MAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,YAAY,OAAOA,UAAU,WAAW;AACzF,WAAOA;EACR;AAEA,MAAIG,MAAMC,QAAQJ,KAAAA,GAAQ;AACzB,UAAMK,SAAgB,CAAA;AACtB,aAASC,IAAI,GAAGA,IAAIN,MAAMO,QAAQD,KAAK;AACtCD,aAAOC,CAAAA,IAAKP,SAASC,MAAMM,CAAAA,GAAIL,QAAAA;IAChC;AACA,WAAOI;EACR;AAEA,MAAI,OAAOL,UAAU,UAAU;AAC9B,UAAMK,SAAc,CAAC;AACrB,eAAWG,OAAOR,OAAO;AACxB,UAAIS,OAAOC,OAAOV,OAAOQ,GAAAA,GAAM;AAC9BH,eAAOG,GAAAA,IAAOT,SAASC,MAAMQ,GAAAA,GAAMP,QAAAA;MACpC;IACD;AACA,WAAOI;EACR;AAGA,SAAOJ,WAAW,OAAOD;AAC1B;AAjCgBD;","names":["deepCopy","value","excluded","includes","Array","isArray","result","i","length","key","Object","hasOwn"]}
package/dist/utils.mjs ADDED
@@ -0,0 +1,37 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/utils.ts
5
+ function deepCopy(value, excluded) {
6
+ if (value == null) {
7
+ return value;
8
+ }
9
+ if (excluded && excluded.includes(value)) {
10
+ return null;
11
+ }
12
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
13
+ return value;
14
+ }
15
+ if (Array.isArray(value)) {
16
+ const result = [];
17
+ for (let i = 0; i < value.length; i++) {
18
+ result[i] = deepCopy(value[i], excluded);
19
+ }
20
+ return result;
21
+ }
22
+ if (typeof value === "object") {
23
+ const result = {};
24
+ for (const key in value) {
25
+ if (Object.hasOwn(value, key)) {
26
+ result[key] = deepCopy(value[key], excluded);
27
+ }
28
+ }
29
+ return result;
30
+ }
31
+ return excluded ? null : value;
32
+ }
33
+ __name(deepCopy, "deepCopy");
34
+ export {
35
+ deepCopy
36
+ };
37
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["/**\n * Deep copy a value, optionally skipping excluded references.\n *\n * @param value - The value to deep copy\n * @param excluded - Optional array of object references to skip (replaced with null)\n */\nexport function deepCopy(value: any, excluded?: any[]): any {\n\tif (value == null) {\n\t\treturn value;\n\t}\n\n\tif (excluded && excluded.includes(value)) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn value;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tconst result: any[] = [];\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tresult[i] = deepCopy(value[i], excluded);\n\t\t}\n\t\treturn result;\n\t}\n\n\tif (typeof value === \"object\") {\n\t\tconst result: any = {};\n\t\tfor (const key in value) {\n\t\t\tif (Object.hasOwn(value, key)) {\n\t\t\t\tresult[key] = deepCopy(value[key], excluded);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t// Non-serializable types: return null when filtering, passthrough otherwise\n\treturn excluded ? null : value;\n}\n"],"mappings":";;;;AAMO,SAASA,SAASC,OAAYC,UAAgB;AACpD,MAAID,SAAS,MAAM;AAClB,WAAOA;EACR;AAEA,MAAIC,YAAYA,SAASC,SAASF,KAAAA,GAAQ;AACzC,WAAO;EACR;AAEA,MAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,YAAY,OAAOA,UAAU,WAAW;AACzF,WAAOA;EACR;AAEA,MAAIG,MAAMC,QAAQJ,KAAAA,GAAQ;AACzB,UAAMK,SAAgB,CAAA;AACtB,aAASC,IAAI,GAAGA,IAAIN,MAAMO,QAAQD,KAAK;AACtCD,aAAOC,CAAAA,IAAKP,SAASC,MAAMM,CAAAA,GAAIL,QAAAA;IAChC;AACA,WAAOI;EACR;AAEA,MAAI,OAAOL,UAAU,UAAU;AAC9B,UAAMK,SAAc,CAAC;AACrB,eAAWG,OAAOR,OAAO;AACxB,UAAIS,OAAOC,OAAOV,OAAOQ,GAAAA,GAAM;AAC9BH,eAAOG,GAAAA,IAAOT,SAASC,MAAMQ,GAAAA,GAAMP,QAAAA;MACpC;IACD;AACA,WAAOI;EACR;AAGA,SAAOJ,WAAW,OAAOD;AAC1B;AAjCgBD;","names":["deepCopy","value","excluded","includes","Array","isArray","result","i","length","key","Object","hasOwn"]}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@al8b/time",
3
+ "version": "0.1.0",
4
+ "sideEffects": false,
5
+ "files": [
6
+ "dist/**/*",
7
+ "README.md",
8
+ "package.json"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsup",
12
+ "clean": "bun --bun ../../../scripts/clean-package.mjs dist",
13
+ "test": "vitest run --passWithNoTests"
14
+ },
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.mjs",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.mjs",
22
+ "require": "./dist/index.js"
23
+ }
24
+ },
25
+ "dependencies": {
26
+ "@al8b/diagnostics": "workspace:*"
27
+ },
28
+ "keywords": [
29
+ "time",
30
+ "time-machine",
31
+ "debugging",
32
+ "replay"
33
+ ],
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
37
+ }