@voidhash/mimic-effect 1.0.0-beta.1 → 1.0.0-beta.10

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 (142) hide show
  1. package/.turbo/turbo-build.log +116 -74
  2. package/dist/ColdStorage.cjs +9 -5
  3. package/dist/ColdStorage.d.cts.map +1 -1
  4. package/dist/ColdStorage.d.mts.map +1 -1
  5. package/dist/ColdStorage.mjs +9 -5
  6. package/dist/ColdStorage.mjs.map +1 -1
  7. package/dist/DocumentInstance.cjs +263 -0
  8. package/dist/DocumentInstance.d.cts +78 -0
  9. package/dist/DocumentInstance.d.cts.map +1 -0
  10. package/dist/DocumentInstance.d.mts +78 -0
  11. package/dist/DocumentInstance.d.mts.map +1 -0
  12. package/dist/DocumentInstance.mjs +264 -0
  13. package/dist/DocumentInstance.mjs.map +1 -0
  14. package/dist/Errors.cjs +10 -1
  15. package/dist/Errors.d.cts +18 -3
  16. package/dist/Errors.d.cts.map +1 -1
  17. package/dist/Errors.d.mts +18 -3
  18. package/dist/Errors.d.mts.map +1 -1
  19. package/dist/Errors.mjs +9 -1
  20. package/dist/Errors.mjs.map +1 -1
  21. package/dist/HotStorage.cjs +39 -12
  22. package/dist/HotStorage.d.cts +17 -1
  23. package/dist/HotStorage.d.cts.map +1 -1
  24. package/dist/HotStorage.d.mts +17 -1
  25. package/dist/HotStorage.d.mts.map +1 -1
  26. package/dist/HotStorage.mjs +39 -12
  27. package/dist/HotStorage.mjs.map +1 -1
  28. package/dist/Metrics.cjs +29 -1
  29. package/dist/Metrics.d.cts +5 -0
  30. package/dist/Metrics.d.cts.map +1 -1
  31. package/dist/Metrics.d.mts +5 -0
  32. package/dist/Metrics.d.mts.map +1 -1
  33. package/dist/Metrics.mjs +26 -1
  34. package/dist/Metrics.mjs.map +1 -1
  35. package/dist/MimicClusterServerEngine.cjs +44 -139
  36. package/dist/MimicClusterServerEngine.d.cts.map +1 -1
  37. package/dist/MimicClusterServerEngine.d.mts +1 -1
  38. package/dist/MimicClusterServerEngine.d.mts.map +1 -1
  39. package/dist/MimicClusterServerEngine.mjs +46 -141
  40. package/dist/MimicClusterServerEngine.mjs.map +1 -1
  41. package/dist/MimicServer.cjs +20 -20
  42. package/dist/MimicServer.d.cts.map +1 -1
  43. package/dist/MimicServer.d.mts.map +1 -1
  44. package/dist/MimicServer.mjs +20 -20
  45. package/dist/MimicServer.mjs.map +1 -1
  46. package/dist/MimicServerEngine.cjs +92 -11
  47. package/dist/MimicServerEngine.d.cts +12 -4
  48. package/dist/MimicServerEngine.d.cts.map +1 -1
  49. package/dist/MimicServerEngine.d.mts +12 -4
  50. package/dist/MimicServerEngine.d.mts.map +1 -1
  51. package/dist/MimicServerEngine.mjs +94 -13
  52. package/dist/MimicServerEngine.mjs.map +1 -1
  53. package/dist/PresenceManager.cjs +5 -5
  54. package/dist/PresenceManager.d.cts.map +1 -1
  55. package/dist/PresenceManager.d.mts.map +1 -1
  56. package/dist/PresenceManager.mjs +5 -5
  57. package/dist/PresenceManager.mjs.map +1 -1
  58. package/dist/Protocol.d.cts +1 -1
  59. package/dist/Protocol.d.mts +1 -1
  60. package/dist/Types.d.cts +9 -2
  61. package/dist/Types.d.cts.map +1 -1
  62. package/dist/Types.d.mts +9 -2
  63. package/dist/Types.d.mts.map +1 -1
  64. package/dist/index.cjs +5 -6
  65. package/dist/index.d.cts +3 -3
  66. package/dist/index.d.mts +3 -3
  67. package/dist/index.mjs +3 -3
  68. package/dist/testing/ColdStorageTestSuite.cjs +508 -0
  69. package/dist/testing/ColdStorageTestSuite.d.cts +36 -0
  70. package/dist/testing/ColdStorageTestSuite.d.cts.map +1 -0
  71. package/dist/testing/ColdStorageTestSuite.d.mts +36 -0
  72. package/dist/testing/ColdStorageTestSuite.d.mts.map +1 -0
  73. package/dist/testing/ColdStorageTestSuite.mjs +508 -0
  74. package/dist/testing/ColdStorageTestSuite.mjs.map +1 -0
  75. package/dist/testing/FailingStorage.cjs +162 -0
  76. package/dist/testing/FailingStorage.d.cts +43 -0
  77. package/dist/testing/FailingStorage.d.cts.map +1 -0
  78. package/dist/testing/FailingStorage.d.mts +43 -0
  79. package/dist/testing/FailingStorage.d.mts.map +1 -0
  80. package/dist/testing/FailingStorage.mjs +163 -0
  81. package/dist/testing/FailingStorage.mjs.map +1 -0
  82. package/dist/testing/HotStorageTestSuite.cjs +820 -0
  83. package/dist/testing/HotStorageTestSuite.d.cts +42 -0
  84. package/dist/testing/HotStorageTestSuite.d.cts.map +1 -0
  85. package/dist/testing/HotStorageTestSuite.d.mts +42 -0
  86. package/dist/testing/HotStorageTestSuite.d.mts.map +1 -0
  87. package/dist/testing/HotStorageTestSuite.mjs +820 -0
  88. package/dist/testing/HotStorageTestSuite.mjs.map +1 -0
  89. package/dist/testing/StorageIntegrationTestSuite.cjs +487 -0
  90. package/dist/testing/StorageIntegrationTestSuite.d.cts +37 -0
  91. package/dist/testing/StorageIntegrationTestSuite.d.cts.map +1 -0
  92. package/dist/testing/StorageIntegrationTestSuite.d.mts +37 -0
  93. package/dist/testing/StorageIntegrationTestSuite.d.mts.map +1 -0
  94. package/dist/testing/StorageIntegrationTestSuite.mjs +487 -0
  95. package/dist/testing/StorageIntegrationTestSuite.mjs.map +1 -0
  96. package/dist/testing/assertions.cjs +117 -0
  97. package/dist/testing/assertions.mjs +112 -0
  98. package/dist/testing/assertions.mjs.map +1 -0
  99. package/dist/testing/index.cjs +14 -0
  100. package/dist/testing/index.d.cts +6 -0
  101. package/dist/testing/index.d.mts +6 -0
  102. package/dist/testing/index.mjs +7 -0
  103. package/dist/testing/types.cjs +15 -0
  104. package/dist/testing/types.d.cts +90 -0
  105. package/dist/testing/types.d.cts.map +1 -0
  106. package/dist/testing/types.d.mts +90 -0
  107. package/dist/testing/types.d.mts.map +1 -0
  108. package/dist/testing/types.mjs +16 -0
  109. package/dist/testing/types.mjs.map +1 -0
  110. package/package.json +8 -3
  111. package/src/ColdStorage.ts +21 -12
  112. package/src/DocumentInstance.ts +527 -0
  113. package/src/Errors.ts +15 -1
  114. package/src/HotStorage.ts +115 -24
  115. package/src/Metrics.ts +30 -0
  116. package/src/MimicClusterServerEngine.ts +120 -275
  117. package/src/MimicServer.ts +83 -75
  118. package/src/MimicServerEngine.ts +230 -30
  119. package/src/PresenceManager.ts +44 -34
  120. package/src/Types.ts +9 -2
  121. package/src/index.ts +5 -35
  122. package/src/testing/ColdStorageTestSuite.ts +589 -0
  123. package/src/testing/FailingStorage.ts +338 -0
  124. package/src/testing/HotStorageTestSuite.ts +1105 -0
  125. package/src/testing/StorageIntegrationTestSuite.ts +736 -0
  126. package/src/testing/assertions.ts +188 -0
  127. package/src/testing/index.ts +83 -0
  128. package/src/testing/types.ts +100 -0
  129. package/tests/ColdStorage.test.ts +8 -120
  130. package/tests/DocumentInstance.test.ts +669 -0
  131. package/tests/HotStorage.test.ts +7 -126
  132. package/tests/StorageIntegration.test.ts +259 -0
  133. package/tsdown.config.ts +1 -1
  134. package/dist/DocumentManager.cjs +0 -229
  135. package/dist/DocumentManager.d.cts +0 -59
  136. package/dist/DocumentManager.d.cts.map +0 -1
  137. package/dist/DocumentManager.d.mts +0 -59
  138. package/dist/DocumentManager.d.mts.map +0 -1
  139. package/dist/DocumentManager.mjs +0 -227
  140. package/dist/DocumentManager.mjs.map +0 -1
  141. package/src/DocumentManager.ts +0 -506
  142. package/tests/DocumentManager.test.ts +0 -335
@@ -0,0 +1,117 @@
1
+ const require_types = require('./types.cjs');
2
+ let effect = require("effect");
3
+
4
+ //#region src/testing/assertions.ts
5
+ /**
6
+ * @voidhash/mimic-effect/testing - Assertion Helpers
7
+ *
8
+ * Internal assertion helpers used by the test suites.
9
+ */
10
+ /**
11
+ * Deep equality check that handles objects, arrays, and primitives.
12
+ * Skips function properties since reconstructed objects (like OperationPath)
13
+ * will have new function instances even when the underlying data is identical.
14
+ */
15
+ const isDeepEqual = (a, b) => {
16
+ if (a === b) return true;
17
+ if (a === null || b === null) return a === b;
18
+ if (a === void 0 || b === void 0) return a === b;
19
+ if (typeof a !== typeof b) return false;
20
+ if (typeof a === "function" && typeof b === "function") return true;
21
+ if (typeof a === "number" && typeof b === "number") {
22
+ if (Number.isNaN(a) && Number.isNaN(b)) return true;
23
+ return a === b;
24
+ }
25
+ if (Array.isArray(a) && Array.isArray(b)) {
26
+ if (a.length !== b.length) return false;
27
+ for (let i = 0; i < a.length; i++) if (!isDeepEqual(a[i], b[i])) return false;
28
+ return true;
29
+ }
30
+ if (typeof a === "object" && typeof b === "object") {
31
+ const aObj = a;
32
+ const bObj = b;
33
+ const aKeys = Object.keys(aObj).filter((k) => typeof aObj[k] !== "function");
34
+ const bKeys = Object.keys(bObj).filter((k) => typeof bObj[k] !== "function");
35
+ if (aKeys.length !== bKeys.length) return false;
36
+ for (const key of aKeys) {
37
+ if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;
38
+ if (!isDeepEqual(aObj[key], bObj[key])) return false;
39
+ }
40
+ return true;
41
+ }
42
+ return false;
43
+ };
44
+ /**
45
+ * Assert that two values are deeply equal.
46
+ */
47
+ const assertEqual = (actual, expected, message) => effect.Effect.gen(function* () {
48
+ if (!isDeepEqual(actual, expected)) yield* effect.Effect.fail(new require_types.TestError({
49
+ message,
50
+ expected,
51
+ actual
52
+ }));
53
+ });
54
+ /**
55
+ * Assert that a condition is true.
56
+ */
57
+ const assertTrue = (condition, message) => effect.Effect.gen(function* () {
58
+ if (!condition) yield* effect.Effect.fail(new require_types.TestError({ message }));
59
+ });
60
+ /**
61
+ * Assert that a value is undefined.
62
+ */
63
+ const assertUndefined = (value, message) => effect.Effect.gen(function* () {
64
+ if (value !== void 0) yield* effect.Effect.fail(new require_types.TestError({
65
+ message,
66
+ expected: void 0,
67
+ actual: value
68
+ }));
69
+ });
70
+ /**
71
+ * Assert that a value is defined (not undefined).
72
+ */
73
+ const assertDefined = (value, message) => effect.Effect.gen(function* () {
74
+ if (value === void 0) yield* effect.Effect.fail(new require_types.TestError({
75
+ message,
76
+ expected: "defined value",
77
+ actual: void 0
78
+ }));
79
+ return value;
80
+ });
81
+ /**
82
+ * Assert that an array has the expected length.
83
+ */
84
+ const assertLength = (array, expectedLength, message) => effect.Effect.gen(function* () {
85
+ if (array.length !== expectedLength) yield* effect.Effect.fail(new require_types.TestError({
86
+ message,
87
+ expected: expectedLength,
88
+ actual: array.length
89
+ }));
90
+ });
91
+ /**
92
+ * Assert that an array is empty.
93
+ */
94
+ const assertEmpty = (array, message) => assertLength(array, 0, message);
95
+ /**
96
+ * Assert that an array is sorted by a key.
97
+ */
98
+ const assertSortedBy = (array, key, message) => effect.Effect.gen(function* () {
99
+ for (let i = 1; i < array.length; i++) {
100
+ const prev = array[i - 1][key];
101
+ const curr = array[i][key];
102
+ if (prev > curr) yield* effect.Effect.fail(new require_types.TestError({
103
+ message,
104
+ expected: `array sorted by ${String(key)}`,
105
+ actual: `element at index ${i - 1} (${prev}) > element at index ${i} (${curr})`
106
+ }));
107
+ }
108
+ });
109
+
110
+ //#endregion
111
+ exports.assertDefined = assertDefined;
112
+ exports.assertEmpty = assertEmpty;
113
+ exports.assertEqual = assertEqual;
114
+ exports.assertLength = assertLength;
115
+ exports.assertSortedBy = assertSortedBy;
116
+ exports.assertTrue = assertTrue;
117
+ exports.assertUndefined = assertUndefined;
@@ -0,0 +1,112 @@
1
+ import { TestError } from "./types.mjs";
2
+ import { Effect } from "effect";
3
+
4
+ //#region src/testing/assertions.ts
5
+ /**
6
+ * @voidhash/mimic-effect/testing - Assertion Helpers
7
+ *
8
+ * Internal assertion helpers used by the test suites.
9
+ */
10
+ /**
11
+ * Deep equality check that handles objects, arrays, and primitives.
12
+ * Skips function properties since reconstructed objects (like OperationPath)
13
+ * will have new function instances even when the underlying data is identical.
14
+ */
15
+ const isDeepEqual = (a, b) => {
16
+ if (a === b) return true;
17
+ if (a === null || b === null) return a === b;
18
+ if (a === void 0 || b === void 0) return a === b;
19
+ if (typeof a !== typeof b) return false;
20
+ if (typeof a === "function" && typeof b === "function") return true;
21
+ if (typeof a === "number" && typeof b === "number") {
22
+ if (Number.isNaN(a) && Number.isNaN(b)) return true;
23
+ return a === b;
24
+ }
25
+ if (Array.isArray(a) && Array.isArray(b)) {
26
+ if (a.length !== b.length) return false;
27
+ for (let i = 0; i < a.length; i++) if (!isDeepEqual(a[i], b[i])) return false;
28
+ return true;
29
+ }
30
+ if (typeof a === "object" && typeof b === "object") {
31
+ const aObj = a;
32
+ const bObj = b;
33
+ const aKeys = Object.keys(aObj).filter((k) => typeof aObj[k] !== "function");
34
+ const bKeys = Object.keys(bObj).filter((k) => typeof bObj[k] !== "function");
35
+ if (aKeys.length !== bKeys.length) return false;
36
+ for (const key of aKeys) {
37
+ if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;
38
+ if (!isDeepEqual(aObj[key], bObj[key])) return false;
39
+ }
40
+ return true;
41
+ }
42
+ return false;
43
+ };
44
+ /**
45
+ * Assert that two values are deeply equal.
46
+ */
47
+ const assertEqual = (actual, expected, message) => Effect.gen(function* () {
48
+ if (!isDeepEqual(actual, expected)) yield* Effect.fail(new TestError({
49
+ message,
50
+ expected,
51
+ actual
52
+ }));
53
+ });
54
+ /**
55
+ * Assert that a condition is true.
56
+ */
57
+ const assertTrue = (condition, message) => Effect.gen(function* () {
58
+ if (!condition) yield* Effect.fail(new TestError({ message }));
59
+ });
60
+ /**
61
+ * Assert that a value is undefined.
62
+ */
63
+ const assertUndefined = (value, message) => Effect.gen(function* () {
64
+ if (value !== void 0) yield* Effect.fail(new TestError({
65
+ message,
66
+ expected: void 0,
67
+ actual: value
68
+ }));
69
+ });
70
+ /**
71
+ * Assert that a value is defined (not undefined).
72
+ */
73
+ const assertDefined = (value, message) => Effect.gen(function* () {
74
+ if (value === void 0) yield* Effect.fail(new TestError({
75
+ message,
76
+ expected: "defined value",
77
+ actual: void 0
78
+ }));
79
+ return value;
80
+ });
81
+ /**
82
+ * Assert that an array has the expected length.
83
+ */
84
+ const assertLength = (array, expectedLength, message) => Effect.gen(function* () {
85
+ if (array.length !== expectedLength) yield* Effect.fail(new TestError({
86
+ message,
87
+ expected: expectedLength,
88
+ actual: array.length
89
+ }));
90
+ });
91
+ /**
92
+ * Assert that an array is empty.
93
+ */
94
+ const assertEmpty = (array, message) => assertLength(array, 0, message);
95
+ /**
96
+ * Assert that an array is sorted by a key.
97
+ */
98
+ const assertSortedBy = (array, key, message) => Effect.gen(function* () {
99
+ for (let i = 1; i < array.length; i++) {
100
+ const prev = array[i - 1][key];
101
+ const curr = array[i][key];
102
+ if (prev > curr) yield* Effect.fail(new TestError({
103
+ message,
104
+ expected: `array sorted by ${String(key)}`,
105
+ actual: `element at index ${i - 1} (${prev}) > element at index ${i} (${curr})`
106
+ }));
107
+ }
108
+ });
109
+
110
+ //#endregion
111
+ export { assertDefined, assertEmpty, assertEqual, assertLength, assertSortedBy, assertTrue, assertUndefined };
112
+ //# sourceMappingURL=assertions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.mjs","names":[],"sources":["../../src/testing/assertions.ts"],"sourcesContent":["/**\n * @voidhash/mimic-effect/testing - Assertion Helpers\n *\n * Internal assertion helpers used by the test suites.\n */\nimport { Effect } from \"effect\";\nimport { TestError } from \"./types\";\n\n// =============================================================================\n// Deep Equality\n// =============================================================================\n\n/**\n * Deep equality check that handles objects, arrays, and primitives.\n * Skips function properties since reconstructed objects (like OperationPath)\n * will have new function instances even when the underlying data is identical.\n */\nexport const isDeepEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true;\n\n if (a === null || b === null) return a === b;\n if (a === undefined || b === undefined) return a === b;\n\n if (typeof a !== typeof b) return false;\n\n // Skip function comparison - functions with same behavior but different references should be considered equal\n if (typeof a === \"function\" && typeof b === \"function\") return true;\n\n if (typeof a === \"number\" && typeof b === \"number\") {\n if (Number.isNaN(a) && Number.isNaN(b)) return true;\n return a === b;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!isDeepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n if (typeof a === \"object\" && typeof b === \"object\") {\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n\n // Filter out function properties for comparison\n const aKeys = Object.keys(aObj).filter(k => typeof aObj[k] !== \"function\");\n const bKeys = Object.keys(bObj).filter(k => typeof bObj[k] !== \"function\");\n\n if (aKeys.length !== bKeys.length) return false;\n\n for (const key of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;\n if (!isDeepEqual(aObj[key], bObj[key])) return false;\n }\n\n return true;\n }\n\n return false;\n};\n\n// =============================================================================\n// Assertion Helpers\n// =============================================================================\n\n/**\n * Assert that two values are deeply equal.\n */\nexport const assertEqual = <T>(\n actual: T,\n expected: T,\n message: string\n): Effect.Effect<void, TestError> =>\n Effect.gen(function* () {\n if (!isDeepEqual(actual, expected)) {\n yield* Effect.fail(new TestError({ message, expected, actual }));\n }\n });\n\n/**\n * Assert that a condition is true.\n */\nexport const assertTrue = (\n condition: boolean,\n message: string\n): Effect.Effect<void, TestError> =>\n Effect.gen(function* () {\n if (!condition) {\n yield* Effect.fail(new TestError({ message }));\n }\n });\n\n/**\n * Assert that a condition is false.\n */\nexport const assertFalse = (\n condition: boolean,\n message: string\n): Effect.Effect<void, TestError> =>\n Effect.gen(function* () {\n if (condition) {\n yield* Effect.fail(new TestError({ message }));\n }\n });\n\n/**\n * Assert that a value is undefined.\n */\nexport const assertUndefined = (\n value: unknown,\n message: string\n): Effect.Effect<void, TestError> =>\n Effect.gen(function* () {\n if (value !== undefined) {\n yield* Effect.fail(\n new TestError({ message, expected: undefined, actual: value })\n );\n }\n });\n\n/**\n * Assert that a value is defined (not undefined).\n */\nexport const assertDefined = <T>(\n value: T | undefined,\n message: string\n): Effect.Effect<T, TestError> =>\n Effect.gen(function* () {\n if (value === undefined) {\n yield* Effect.fail(\n new TestError({ message, expected: \"defined value\", actual: undefined })\n );\n }\n return value as T;\n });\n\n/**\n * Assert that an array has the expected length.\n */\nexport const assertLength = <T>(\n array: T[],\n expectedLength: number,\n message: string\n): Effect.Effect<void, TestError> =>\n Effect.gen(function* () {\n if (array.length !== expectedLength) {\n yield* Effect.fail(\n new TestError({\n message,\n expected: expectedLength,\n actual: array.length,\n })\n );\n }\n });\n\n/**\n * Assert that an array is empty.\n */\nexport const assertEmpty = <T>(\n array: T[],\n message: string\n): Effect.Effect<void, TestError> => assertLength(array, 0, message);\n\n/**\n * Assert that an array is sorted by a key.\n */\nexport const assertSortedBy = <T>(\n array: T[],\n key: keyof T,\n message: string\n): Effect.Effect<void, TestError> =>\n Effect.gen(function* () {\n for (let i = 1; i < array.length; i++) {\n const prev = array[i - 1]![key];\n const curr = array[i]![key];\n if (prev > curr) {\n yield* Effect.fail(\n new TestError({\n message,\n expected: `array sorted by ${String(key)}`,\n actual: `element at index ${i - 1} (${prev}) > element at index ${i} (${curr})`,\n })\n );\n }\n }\n });\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAa,eAAe,GAAY,MAAwB;AAC9D,KAAI,MAAM,EAAG,QAAO;AAEpB,KAAI,MAAM,QAAQ,MAAM,KAAM,QAAO,MAAM;AAC3C,KAAI,MAAM,UAAa,MAAM,OAAW,QAAO,MAAM;AAErD,KAAI,OAAO,MAAM,OAAO,EAAG,QAAO;AAGlC,KAAI,OAAO,MAAM,cAAc,OAAO,MAAM,WAAY,QAAO;AAE/D,KAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAClD,MAAI,OAAO,MAAM,EAAE,IAAI,OAAO,MAAM,EAAE,CAAE,QAAO;AAC/C,SAAO,MAAM;;AAGf,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,EAAE;AACxC,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,OAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,KAAI,CAAC,YAAY,EAAE,IAAI,EAAE,GAAG,CAAE,QAAO;AAEvC,SAAO;;AAGT,KAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;EAClD,MAAM,OAAO;EACb,MAAM,OAAO;EAGb,MAAM,QAAQ,OAAO,KAAK,KAAK,CAAC,QAAO,MAAK,OAAO,KAAK,OAAO,WAAW;EAC1E,MAAM,QAAQ,OAAO,KAAK,KAAK,CAAC,QAAO,MAAK,OAAO,KAAK,OAAO,WAAW;AAE1E,MAAI,MAAM,WAAW,MAAM,OAAQ,QAAO;AAE1C,OAAK,MAAM,OAAO,OAAO;AACvB,OAAI,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,CAAE,QAAO;AAC7D,OAAI,CAAC,YAAY,KAAK,MAAM,KAAK,KAAK,CAAE,QAAO;;AAGjD,SAAO;;AAGT,QAAO;;;;;AAUT,MAAa,eACX,QACA,UACA,YAEA,OAAO,IAAI,aAAa;AACtB,KAAI,CAAC,YAAY,QAAQ,SAAS,CAChC,QAAO,OAAO,KAAK,IAAI,UAAU;EAAE;EAAS;EAAU;EAAQ,CAAC,CAAC;EAElE;;;;AAKJ,MAAa,cACX,WACA,YAEA,OAAO,IAAI,aAAa;AACtB,KAAI,CAAC,UACH,QAAO,OAAO,KAAK,IAAI,UAAU,EAAE,SAAS,CAAC,CAAC;EAEhD;;;;AAkBJ,MAAa,mBACX,OACA,YAEA,OAAO,IAAI,aAAa;AACtB,KAAI,UAAU,OACZ,QAAO,OAAO,KACZ,IAAI,UAAU;EAAE;EAAS,UAAU;EAAW,QAAQ;EAAO,CAAC,CAC/D;EAEH;;;;AAKJ,MAAa,iBACX,OACA,YAEA,OAAO,IAAI,aAAa;AACtB,KAAI,UAAU,OACZ,QAAO,OAAO,KACZ,IAAI,UAAU;EAAE;EAAS,UAAU;EAAiB,QAAQ;EAAW,CAAC,CACzE;AAEH,QAAO;EACP;;;;AAKJ,MAAa,gBACX,OACA,gBACA,YAEA,OAAO,IAAI,aAAa;AACtB,KAAI,MAAM,WAAW,eACnB,QAAO,OAAO,KACZ,IAAI,UAAU;EACZ;EACA,UAAU;EACV,QAAQ,MAAM;EACf,CAAC,CACH;EAEH;;;;AAKJ,MAAa,eACX,OACA,YACmC,aAAa,OAAO,GAAG,QAAQ;;;;AAKpE,MAAa,kBACX,OACA,KACA,YAEA,OAAO,IAAI,aAAa;AACtB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM,IAAI,GAAI;EAC3B,MAAM,OAAO,MAAM,GAAI;AACvB,MAAI,OAAO,KACT,QAAO,OAAO,KACZ,IAAI,UAAU;GACZ;GACA,UAAU,mBAAmB,OAAO,IAAI;GACxC,QAAQ,oBAAoB,IAAI,EAAE,IAAI,KAAK,uBAAuB,EAAE,IAAI,KAAK;GAC9E,CAAC,CACH;;EAGL"}
@@ -0,0 +1,14 @@
1
+ const require_types = require('./types.cjs');
2
+ const require_ColdStorageTestSuite = require('./ColdStorageTestSuite.cjs');
3
+ const require_HotStorageTestSuite = require('./HotStorageTestSuite.cjs');
4
+ const require_StorageIntegrationTestSuite = require('./StorageIntegrationTestSuite.cjs');
5
+ const require_FailingStorage = require('./FailingStorage.cjs');
6
+
7
+ exports.ColdStorageCategories = require_ColdStorageTestSuite.Categories;
8
+ exports.ColdStorageTestSuite = require_ColdStorageTestSuite.ColdStorageTestSuite;
9
+ exports.FailingStorage = require_FailingStorage.FailingStorage;
10
+ exports.HotStorageCategories = require_HotStorageTestSuite.Categories;
11
+ exports.HotStorageTestSuite = require_HotStorageTestSuite.HotStorageTestSuite;
12
+ exports.IntegrationCategories = require_StorageIntegrationTestSuite.Categories;
13
+ exports.StorageIntegrationTestSuite = require_StorageIntegrationTestSuite.StorageIntegrationTestSuite;
14
+ exports.TestError = require_types.TestError;
@@ -0,0 +1,6 @@
1
+ import { FailedTest, StorageTestCase, TestError, TestResults } from "./types.cjs";
2
+ import { Categories, ColdStorageTestError, ColdStorageTestSuite } from "./ColdStorageTestSuite.cjs";
3
+ import { Categories as Categories$1, HotStorageTestError, HotStorageTestSuite } from "./HotStorageTestSuite.cjs";
4
+ import { Categories as Categories$2, StorageIntegrationTestSuite } from "./StorageIntegrationTestSuite.cjs";
5
+ import { FailingColdStorageConfig, FailingHotStorageConfig, FailingStorage } from "./FailingStorage.cjs";
6
+ export { Categories as ColdStorageCategories, type ColdStorageTestError, ColdStorageTestSuite, type FailedTest, type FailingColdStorageConfig, type FailingHotStorageConfig, FailingStorage, Categories$1 as HotStorageCategories, type HotStorageTestError, HotStorageTestSuite, Categories$2 as IntegrationCategories, StorageIntegrationTestSuite, type StorageTestCase, TestError, type TestResults };
@@ -0,0 +1,6 @@
1
+ import { FailedTest, StorageTestCase, TestError, TestResults } from "./types.mjs";
2
+ import { Categories, ColdStorageTestError, ColdStorageTestSuite } from "./ColdStorageTestSuite.mjs";
3
+ import { Categories as Categories$1, HotStorageTestError, HotStorageTestSuite } from "./HotStorageTestSuite.mjs";
4
+ import { Categories as Categories$2, StorageIntegrationTestSuite } from "./StorageIntegrationTestSuite.mjs";
5
+ import { FailingColdStorageConfig, FailingHotStorageConfig, FailingStorage } from "./FailingStorage.mjs";
6
+ export { Categories as ColdStorageCategories, type ColdStorageTestError, ColdStorageTestSuite, type FailedTest, type FailingColdStorageConfig, type FailingHotStorageConfig, FailingStorage, Categories$1 as HotStorageCategories, type HotStorageTestError, HotStorageTestSuite, Categories$2 as IntegrationCategories, StorageIntegrationTestSuite, type StorageTestCase, TestError, type TestResults };
@@ -0,0 +1,7 @@
1
+ import { TestError } from "./types.mjs";
2
+ import { Categories, ColdStorageTestSuite } from "./ColdStorageTestSuite.mjs";
3
+ import { Categories as Categories$1, HotStorageTestSuite } from "./HotStorageTestSuite.mjs";
4
+ import { Categories as Categories$2, StorageIntegrationTestSuite } from "./StorageIntegrationTestSuite.mjs";
5
+ import { FailingStorage } from "./FailingStorage.mjs";
6
+
7
+ export { Categories as ColdStorageCategories, ColdStorageTestSuite, FailingStorage, Categories$1 as HotStorageCategories, HotStorageTestSuite, Categories$2 as IntegrationCategories, StorageIntegrationTestSuite, TestError };
@@ -0,0 +1,15 @@
1
+ let effect = require("effect");
2
+
3
+ //#region src/testing/types.ts
4
+ /**
5
+ * @voidhash/mimic-effect/testing - Core Types
6
+ *
7
+ * Types used by the storage adapter test utilities.
8
+ */
9
+ /**
10
+ * Error thrown when a test assertion fails.
11
+ */
12
+ var TestError = class extends effect.Data.TaggedError("TestError") {};
13
+
14
+ //#endregion
15
+ exports.TestError = TestError;
@@ -0,0 +1,90 @@
1
+ import { Effect } from "effect";
2
+ import * as effect_Types7 from "effect/Types";
3
+ import * as effect_Cause7 from "effect/Cause";
4
+
5
+ //#region src/testing/types.d.ts
6
+
7
+ declare const TestError_base: new <A extends Record<string, any> = {}>(args: effect_Types7.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause7.YieldableError & {
8
+ readonly _tag: "TestError";
9
+ } & Readonly<A>;
10
+ /**
11
+ * Error thrown when a test assertion fails.
12
+ */
13
+ declare class TestError extends TestError_base<{
14
+ /** Description of what failed */
15
+ readonly message: string;
16
+ /** Expected value (if applicable) */
17
+ readonly expected?: unknown;
18
+ /** Actual value received (if applicable) */
19
+ readonly actual?: unknown;
20
+ }> {}
21
+ /**
22
+ * A single storage adapter test case.
23
+ *
24
+ * Test cases are framework-agnostic Effects that can be run with any test runner.
25
+ *
26
+ * @template E - The error type for this test case
27
+ * @template R - The Effect requirements (e.g., ColdStorageTag or HotStorageTag)
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Using with vitest
32
+ * const tests = ColdStorageTestSuite.makeTests();
33
+ *
34
+ * describe("MyAdapter", () => {
35
+ * for (const test of tests) {
36
+ * it(test.name, () =>
37
+ * Effect.runPromise(test.run.pipe(Effect.provide(myAdapterLayer)))
38
+ * );
39
+ * }
40
+ * });
41
+ * ```
42
+ */
43
+ interface StorageTestCase<E, R> {
44
+ /** Human-readable test name */
45
+ readonly name: string;
46
+ /** Category for grouping (e.g., "Basic Operations", "Data Integrity") */
47
+ readonly category: string;
48
+ /** The test as an Effect - succeeds if test passes, fails with error if not */
49
+ readonly run: Effect.Effect<void, E, R>;
50
+ }
51
+ /**
52
+ * Result of a failed test.
53
+ */
54
+ interface FailedTest<E, R> {
55
+ /** The test case that failed */
56
+ readonly test: StorageTestCase<E, R>;
57
+ /** The error that caused the failure */
58
+ readonly error: E;
59
+ }
60
+ /**
61
+ * Results from running all tests in a suite.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const results = await Effect.runPromise(
66
+ * ColdStorageTestSuite.runAll().pipe(Effect.provide(myAdapterLayer))
67
+ * );
68
+ *
69
+ * console.log(`Passed: ${results.passCount}/${results.total}`);
70
+ *
71
+ * for (const { test, error } of results.failed) {
72
+ * console.error(`FAIL: ${test.name} - ${error._tag}`);
73
+ * }
74
+ * ```
75
+ */
76
+ interface TestResults<E, R> {
77
+ /** Tests that passed */
78
+ readonly passed: StorageTestCase<E, R>[];
79
+ /** Tests that failed with their errors */
80
+ readonly failed: FailedTest<E, R>[];
81
+ /** Total number of tests run */
82
+ readonly total: number;
83
+ /** Number of tests that passed */
84
+ readonly passCount: number;
85
+ /** Number of tests that failed */
86
+ readonly failCount: number;
87
+ }
88
+ //#endregion
89
+ export { FailedTest, StorageTestCase, TestError, TestResults };
90
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/testing/types.ts"],"sourcesContent":[],"mappings":";;;;;;cAKsC;;;;;;cASzB,SAAA,SAAkB;;;;;;EAAlB,SAAA,MAAU,CAAA,EAAA,OAAQ;AAmC/B,CAAA,CAAA,CAAA;;;;AAgBA;;;;;;AAuBA;;;;;;;;;;;;;UAvCiB;;;;;;gBAMD,MAAA,CAAO,aAAa,GAAG;;;;;UAUtB;;iBAEA,gBAAgB,GAAG;;kBAElB;;;;;;;;;;;;;;;;;;UAmBD;;mBAEE,gBAAgB,GAAG;;mBAEnB,WAAW,GAAG"}
@@ -0,0 +1,90 @@
1
+ import { Effect } from "effect";
2
+ import * as effect_Types0 from "effect/Types";
3
+ import * as effect_Cause0 from "effect/Cause";
4
+
5
+ //#region src/testing/types.d.ts
6
+
7
+ declare const TestError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
8
+ readonly _tag: "TestError";
9
+ } & Readonly<A>;
10
+ /**
11
+ * Error thrown when a test assertion fails.
12
+ */
13
+ declare class TestError extends TestError_base<{
14
+ /** Description of what failed */
15
+ readonly message: string;
16
+ /** Expected value (if applicable) */
17
+ readonly expected?: unknown;
18
+ /** Actual value received (if applicable) */
19
+ readonly actual?: unknown;
20
+ }> {}
21
+ /**
22
+ * A single storage adapter test case.
23
+ *
24
+ * Test cases are framework-agnostic Effects that can be run with any test runner.
25
+ *
26
+ * @template E - The error type for this test case
27
+ * @template R - The Effect requirements (e.g., ColdStorageTag or HotStorageTag)
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Using with vitest
32
+ * const tests = ColdStorageTestSuite.makeTests();
33
+ *
34
+ * describe("MyAdapter", () => {
35
+ * for (const test of tests) {
36
+ * it(test.name, () =>
37
+ * Effect.runPromise(test.run.pipe(Effect.provide(myAdapterLayer)))
38
+ * );
39
+ * }
40
+ * });
41
+ * ```
42
+ */
43
+ interface StorageTestCase<E, R> {
44
+ /** Human-readable test name */
45
+ readonly name: string;
46
+ /** Category for grouping (e.g., "Basic Operations", "Data Integrity") */
47
+ readonly category: string;
48
+ /** The test as an Effect - succeeds if test passes, fails with error if not */
49
+ readonly run: Effect.Effect<void, E, R>;
50
+ }
51
+ /**
52
+ * Result of a failed test.
53
+ */
54
+ interface FailedTest<E, R> {
55
+ /** The test case that failed */
56
+ readonly test: StorageTestCase<E, R>;
57
+ /** The error that caused the failure */
58
+ readonly error: E;
59
+ }
60
+ /**
61
+ * Results from running all tests in a suite.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const results = await Effect.runPromise(
66
+ * ColdStorageTestSuite.runAll().pipe(Effect.provide(myAdapterLayer))
67
+ * );
68
+ *
69
+ * console.log(`Passed: ${results.passCount}/${results.total}`);
70
+ *
71
+ * for (const { test, error } of results.failed) {
72
+ * console.error(`FAIL: ${test.name} - ${error._tag}`);
73
+ * }
74
+ * ```
75
+ */
76
+ interface TestResults<E, R> {
77
+ /** Tests that passed */
78
+ readonly passed: StorageTestCase<E, R>[];
79
+ /** Tests that failed with their errors */
80
+ readonly failed: FailedTest<E, R>[];
81
+ /** Total number of tests run */
82
+ readonly total: number;
83
+ /** Number of tests that passed */
84
+ readonly passCount: number;
85
+ /** Number of tests that failed */
86
+ readonly failCount: number;
87
+ }
88
+ //#endregion
89
+ export { FailedTest, StorageTestCase, TestError, TestResults };
90
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/testing/types.ts"],"sourcesContent":[],"mappings":";;;;;;cAKsC;;;;;;cASzB,SAAA,SAAkB;;;;;;EAAlB,SAAA,MAAU,CAAA,EAAA,OAAQ;AAmC/B,CAAA,CAAA,CAAA;;;;AAgBA;;;;;;AAuBA;;;;;;;;;;;;;UAvCiB;;;;;;gBAMD,MAAA,CAAO,aAAa,GAAG;;;;;UAUtB;;iBAEA,gBAAgB,GAAG;;kBAElB;;;;;;;;;;;;;;;;;;UAmBD;;mBAEE,gBAAgB,GAAG;;mBAEnB,WAAW,GAAG"}
@@ -0,0 +1,16 @@
1
+ import { Data } from "effect";
2
+
3
+ //#region src/testing/types.ts
4
+ /**
5
+ * @voidhash/mimic-effect/testing - Core Types
6
+ *
7
+ * Types used by the storage adapter test utilities.
8
+ */
9
+ /**
10
+ * Error thrown when a test assertion fails.
11
+ */
12
+ var TestError = class extends Data.TaggedError("TestError") {};
13
+
14
+ //#endregion
15
+ export { TestError };
16
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","names":[],"sources":["../../src/testing/types.ts"],"sourcesContent":["/**\n * @voidhash/mimic-effect/testing - Core Types\n *\n * Types used by the storage adapter test utilities.\n */\nimport { Data, Effect } from \"effect\";\n\n// =============================================================================\n// Error Types\n// =============================================================================\n\n/**\n * Error thrown when a test assertion fails.\n */\nexport class TestError extends Data.TaggedError(\"TestError\")<{\n /** Description of what failed */\n readonly message: string;\n /** Expected value (if applicable) */\n readonly expected?: unknown;\n /** Actual value received (if applicable) */\n readonly actual?: unknown;\n}> {}\n\n// =============================================================================\n// Test Case Types\n// =============================================================================\n\n/**\n * A single storage adapter test case.\n *\n * Test cases are framework-agnostic Effects that can be run with any test runner.\n *\n * @template E - The error type for this test case\n * @template R - The Effect requirements (e.g., ColdStorageTag or HotStorageTag)\n *\n * @example\n * ```typescript\n * // Using with vitest\n * const tests = ColdStorageTestSuite.makeTests();\n *\n * describe(\"MyAdapter\", () => {\n * for (const test of tests) {\n * it(test.name, () =>\n * Effect.runPromise(test.run.pipe(Effect.provide(myAdapterLayer)))\n * );\n * }\n * });\n * ```\n */\nexport interface StorageTestCase<E, R> {\n /** Human-readable test name */\n readonly name: string;\n /** Category for grouping (e.g., \"Basic Operations\", \"Data Integrity\") */\n readonly category: string;\n /** The test as an Effect - succeeds if test passes, fails with error if not */\n readonly run: Effect.Effect<void, E, R>;\n}\n\n// =============================================================================\n// Test Results Types\n// =============================================================================\n\n/**\n * Result of a failed test.\n */\nexport interface FailedTest<E, R> {\n /** The test case that failed */\n readonly test: StorageTestCase<E, R>;\n /** The error that caused the failure */\n readonly error: E;\n}\n\n/**\n * Results from running all tests in a suite.\n *\n * @example\n * ```typescript\n * const results = await Effect.runPromise(\n * ColdStorageTestSuite.runAll().pipe(Effect.provide(myAdapterLayer))\n * );\n *\n * console.log(`Passed: ${results.passCount}/${results.total}`);\n *\n * for (const { test, error } of results.failed) {\n * console.error(`FAIL: ${test.name} - ${error._tag}`);\n * }\n * ```\n */\nexport interface TestResults<E, R> {\n /** Tests that passed */\n readonly passed: StorageTestCase<E, R>[];\n /** Tests that failed with their errors */\n readonly failed: FailedTest<E, R>[];\n /** Total number of tests run */\n readonly total: number;\n /** Number of tests that passed */\n readonly passCount: number;\n /** Number of tests that failed */\n readonly failCount: number;\n}\n"],"mappings":";;;;;;;;;;;AAcA,IAAa,YAAb,cAA+B,KAAK,YAAY,YAAY,CAOzD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidhash/mimic-effect",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.10",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -13,6 +13,11 @@
13
13
  "types": "./dist/index.d.mts",
14
14
  "import": "./dist/index.mjs",
15
15
  "require": "./dist/index.cjs"
16
+ },
17
+ "./testing": {
18
+ "types": "./dist/testing/index.d.mts",
19
+ "import": "./dist/testing/index.mjs",
20
+ "require": "./dist/testing/index.cjs"
16
21
  }
17
22
  },
18
23
  "devDependencies": {
@@ -21,14 +26,14 @@
21
26
  "typescript": "5.8.3",
22
27
  "vite-tsconfig-paths": "^5.1.4",
23
28
  "vitest": "^3.2.4",
24
- "@voidhash/tsconfig": "1.0.0-beta.1"
29
+ "@voidhash/tsconfig": "1.0.0-beta.10"
25
30
  },
26
31
  "peerDependencies": {
27
32
  "@effect/platform": "^0.93.8",
28
33
  "@effect/cluster": "^0.55.0",
29
34
  "@effect/rpc": "^0.72.2",
30
35
  "effect": "^3.19.12",
31
- "@voidhash/mimic": "1.0.0-beta.1"
36
+ "@voidhash/mimic": "1.0.0-beta.10"
32
37
  },
33
38
  "peerDependenciesMeta": {
34
39
  "@effect/cluster": {
@@ -104,24 +104,33 @@ export namespace InMemory {
104
104
  export const make = (): Layer.Layer<ColdStorageTag> =>
105
105
  Layer.effect(
106
106
  ColdStorageTag,
107
- Effect.gen(function* () {
107
+ Effect.fn("cold-storage.in-memory.create")(function* () {
108
108
  const store = yield* Ref.make(HashMap.empty<string, StoredDocument>());
109
109
 
110
110
  return {
111
- load: (documentId) =>
112
- Effect.gen(function* () {
113
- const current = yield* Ref.get(store);
114
- const result = HashMap.get(current, documentId);
115
- return result._tag === "Some" ? result.value : undefined;
116
- }),
111
+ load: Effect.fn("cold-storage.load")(function* (documentId: string) {
112
+ const current = yield* Ref.get(store);
113
+ const result = HashMap.get(current, documentId);
114
+ return result._tag === "Some" ? result.value : undefined;
115
+ }),
117
116
 
118
- save: (documentId, document) =>
119
- Ref.update(store, (map) => HashMap.set(map, documentId, document)),
117
+ save: Effect.fn("cold-storage.save")(
118
+ function* (documentId: string, document: StoredDocument) {
119
+ yield* Ref.update(store, (map) =>
120
+ HashMap.set(map, documentId, document)
121
+ );
122
+ }
123
+ ),
120
124
 
121
- delete: (documentId) =>
122
- Ref.update(store, (map) => HashMap.remove(map, documentId)),
125
+ delete: Effect.fn("cold-storage.delete")(
126
+ function* (documentId: string) {
127
+ yield* Ref.update(store, (map) =>
128
+ HashMap.remove(map, documentId)
129
+ );
130
+ }
131
+ ),
123
132
  };
124
- })
133
+ })()
125
134
  );
126
135
  }
127
136