@voidhash/mimic 1.0.0-beta.16 → 1.0.0-beta.17

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 (95) hide show
  1. package/dist/EffectSchema.cjs +3 -3
  2. package/dist/EffectSchema.d.cts +5 -5
  3. package/dist/EffectSchema.d.cts.map +1 -1
  4. package/dist/EffectSchema.d.mts +5 -5
  5. package/dist/EffectSchema.d.mts.map +1 -1
  6. package/dist/EffectSchema.mjs +3 -3
  7. package/dist/EffectSchema.mjs.map +1 -1
  8. package/dist/FractionalIndex.mjs.map +1 -1
  9. package/dist/Operation.d.cts +4 -4
  10. package/dist/Operation.d.cts.map +1 -1
  11. package/dist/Operation.d.mts +4 -4
  12. package/dist/Operation.d.mts.map +1 -1
  13. package/dist/Operation.mjs.map +1 -1
  14. package/dist/OperationDefinition.d.cts +2 -2
  15. package/dist/OperationDefinition.d.cts.map +1 -1
  16. package/dist/OperationDefinition.d.mts +2 -2
  17. package/dist/OperationDefinition.d.mts.map +1 -1
  18. package/dist/OperationDefinition.mjs.map +1 -1
  19. package/dist/Presence.mjs.map +1 -1
  20. package/dist/SchemaJSON.cjs +305 -0
  21. package/dist/SchemaJSON.d.cts +11 -0
  22. package/dist/SchemaJSON.d.cts.map +1 -0
  23. package/dist/SchemaJSON.d.mts +11 -0
  24. package/dist/SchemaJSON.d.mts.map +1 -0
  25. package/dist/SchemaJSON.mjs +301 -0
  26. package/dist/SchemaJSON.mjs.map +1 -0
  27. package/dist/index.cjs +7 -0
  28. package/dist/index.d.cts +2 -1
  29. package/dist/index.d.mts +2 -1
  30. package/dist/index.mjs +2 -1
  31. package/dist/primitives/Array.cjs +12 -2
  32. package/dist/primitives/Array.d.cts.map +1 -1
  33. package/dist/primitives/Array.d.mts.map +1 -1
  34. package/dist/primitives/Array.mjs +12 -2
  35. package/dist/primitives/Array.mjs.map +1 -1
  36. package/dist/primitives/Boolean.mjs.map +1 -1
  37. package/dist/primitives/Either.mjs.map +1 -1
  38. package/dist/primitives/Literal.mjs.map +1 -1
  39. package/dist/primitives/Number.cjs +27 -5
  40. package/dist/primitives/Number.d.cts.map +1 -1
  41. package/dist/primitives/Number.d.mts.map +1 -1
  42. package/dist/primitives/Number.mjs +27 -5
  43. package/dist/primitives/Number.mjs.map +1 -1
  44. package/dist/primitives/String.cjs +44 -13
  45. package/dist/primitives/String.d.cts.map +1 -1
  46. package/dist/primitives/String.d.mts.map +1 -1
  47. package/dist/primitives/String.mjs +44 -13
  48. package/dist/primitives/String.mjs.map +1 -1
  49. package/dist/primitives/Union.mjs.map +1 -1
  50. package/dist/primitives/shared.d.cts +2 -0
  51. package/dist/primitives/shared.d.cts.map +1 -1
  52. package/dist/primitives/shared.d.mts +2 -0
  53. package/dist/primitives/shared.d.mts.map +1 -1
  54. package/dist/primitives/shared.mjs.map +1 -1
  55. package/package.json +15 -8
  56. package/src/EffectSchema.ts +3 -3
  57. package/src/FractionalIndex.ts +18 -18
  58. package/src/Operation.ts +5 -5
  59. package/src/OperationDefinition.ts +2 -2
  60. package/src/Presence.ts +3 -3
  61. package/src/SchemaJSON.ts +396 -0
  62. package/src/index.ts +1 -0
  63. package/src/primitives/Array.ts +18 -8
  64. package/src/primitives/Boolean.ts +2 -2
  65. package/src/primitives/Either.ts +2 -2
  66. package/src/primitives/Literal.ts +2 -2
  67. package/src/primitives/Number.ts +44 -22
  68. package/src/primitives/String.ts +61 -34
  69. package/src/primitives/Union.ts +1 -1
  70. package/src/primitives/shared.ts +2 -0
  71. package/.turbo/turbo-build.log +0 -270
  72. package/tests/Document.test.ts +0 -557
  73. package/tests/EffectSchema.test.ts +0 -546
  74. package/tests/FractionalIndex.test.ts +0 -377
  75. package/tests/OperationPath.test.ts +0 -151
  76. package/tests/Presence.test.ts +0 -321
  77. package/tests/Primitive.test.ts +0 -381
  78. package/tests/client/ClientDocument.test.ts +0 -1981
  79. package/tests/client/WebSocketTransport.test.ts +0 -1217
  80. package/tests/primitives/Array.test.ts +0 -526
  81. package/tests/primitives/Boolean.test.ts +0 -126
  82. package/tests/primitives/Either.test.ts +0 -707
  83. package/tests/primitives/Lazy.test.ts +0 -143
  84. package/tests/primitives/Literal.test.ts +0 -122
  85. package/tests/primitives/Number.test.ts +0 -133
  86. package/tests/primitives/String.test.ts +0 -128
  87. package/tests/primitives/Struct.test.ts +0 -1154
  88. package/tests/primitives/Tree.test.ts +0 -1139
  89. package/tests/primitives/TreeNode.test.ts +0 -50
  90. package/tests/primitives/Union.test.ts +0 -554
  91. package/tests/server/ServerDocument.test.ts +0 -903
  92. package/tsconfig.build.json +0 -24
  93. package/tsconfig.json +0 -8
  94. package/tsdown.config.ts +0 -18
  95. package/vitest.mts +0 -11
@@ -117,7 +117,7 @@ function buildUnionSetSchema(unionPrimitive) {
117
117
  }
118
118
  if (variantSchemas.length === 0) return effect.Schema.Unknown;
119
119
  if (variantSchemas.length === 1) return variantSchemas[0];
120
- return effect.Schema.Union(...variantSchemas);
120
+ return effect.Schema.Union(variantSchemas);
121
121
  }
122
122
  /**
123
123
  * Build the schema for an either primitive.
@@ -129,7 +129,7 @@ function buildEitherSchema(eitherPrimitive) {
129
129
  for (const variant of variants) variantSchemas.push(getBaseSchema(variant));
130
130
  if (variantSchemas.length === 0) return effect.Schema.Unknown;
131
131
  if (variantSchemas.length === 1) return variantSchemas[0];
132
- return effect.Schema.Union(...variantSchemas);
132
+ return effect.Schema.Union(variantSchemas);
133
133
  }
134
134
  /**
135
135
  * Build the update schema for a union primitive.
@@ -144,7 +144,7 @@ function buildUnionUpdateSchema(unionPrimitive) {
144
144
  }
145
145
  if (variantSchemas.length === 0) return effect.Schema.Unknown;
146
146
  if (variantSchemas.length === 1) return variantSchemas[0];
147
- return effect.Schema.Union(...variantSchemas);
147
+ return effect.Schema.Union(variantSchemas);
148
148
  }
149
149
  /**
150
150
  * Get the update schema for a primitive.
@@ -26,11 +26,11 @@ type ToTreeNodeUpdateSchema<T extends AnyTreeNodePrimitive> = Schema.Schema<Infe
26
26
  * Schema for a tree node state (flat storage format).
27
27
  */
28
28
  declare const TreeNodeStateSchema: Schema.Struct<{
29
- id: typeof Schema.String;
30
- type: typeof Schema.String;
31
- parentId: Schema.NullOr<typeof Schema.String>;
32
- pos: typeof Schema.String;
33
- data: typeof Schema.Unknown;
29
+ readonly id: Schema.String;
30
+ readonly type: Schema.String;
31
+ readonly parentId: Schema.NullOr<Schema.String>;
32
+ readonly pos: Schema.String;
33
+ readonly data: Schema.Unknown;
34
34
  }>;
35
35
  /**
36
36
  * Convert a Mimic primitive to an Effect.Schema for set operations.
@@ -1 +1 @@
1
- {"version":3,"file":"EffectSchema.d.cts","names":[],"sources":["../src/EffectSchema.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;KAsBY,sBAAsB,gBAAgB,MAAA,CAAO,OAAO,cAAc;;;;AAAlE,KAKA,cALW,CAAA,UAKc,YALd,CAAA,GAK8B,MAAA,CAAO,MALrC,CAK4C,gBAL5C,CAK6D,CAL7D,CAAA,CAAA;;;;AAA2B,KAUtC,mBAV6C,CAAA,UAUf,oBAVe,CAAA,GAUS,MAAA,CAAO,MAVhB,CAUuB,aAVvB,CAUqC,CAVrC,CAAA,MAAA,CAAA,CAAA,CAAA;;AAKzD;;AAAoF,KAUxE,sBAVwE,CAAA,UAUvC,oBAVuC,CAAA,GAUf,MAAA,CAAO,MAVQ,CAUD,gBAVC,CAUgB,CAVhB,CAAA,MAAA,CAAA,CAAA,CAAA;;;;AAKxE,cAcC,mBAdkB,EAcC,MAAA,CAAA,MAdD,CAAA;EAAW,EAAA,EAAA,oBAAA;EAAoD,IAAA,EAAA,oBAAA;EAAd,QAAA,eAAA,CAAA,oBAAA,CAAA;EAAd,GAAA,EAAO,oBAAA;EAAM,IAAA,EAAA,qBAAA;AAK/E,CAAA,CAAA;;;;;;AASA;;;;;;;;;AAwSA;;;;;;AACA;;AAAuE,iBADvD,WACuD,CAAA,UADjC,YACiC,CAAA,CAAA,SAAA,EADR,CACQ,CAAA,EADJ,WACI,CADQ,CACR,CAAA;AAAwB,iBAA/E,WAA+E,CAAA,UAAzD,oBAAyD,CAAA,CAAA,SAAA,EAAxB,CAAwB,CAAA,EAApB,mBAAoB,CAAA,CAAA,CAAA;;;AA0B/F;;;;;;AACA;;;;;;;;;;;;;iBADgB,yBAAyB,yBAAyB,IAAI,eAAe;iBACrE,yBAAyB,iCAAiC,IAAI,uBAAuB"}
1
+ {"version":3,"file":"EffectSchema.d.cts","names":[],"sources":["../src/EffectSchema.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;KAsBY,sBAAsB,gBAAgB,MAAA,CAAO,OAAO,cAAc;;;;AAAlE,KAKA,cALW,CAAA,UAKc,YALd,CAAA,GAK8B,MAAA,CAAO,MALrC,CAK4C,gBAL5C,CAK6D,CAL7D,CAAA,CAAA;;;;AAA2B,KAUtC,mBAV6C,CAAA,UAUf,oBAVe,CAAA,GAUS,MAAA,CAAO,MAVhB,CAUuB,aAVvB,CAUqC,CAVrC,CAAA,MAAA,CAAA,CAAA,CAAA;;AAKzD;;AAAoF,KAUxE,sBAVwE,CAAA,UAUvC,oBAVuC,CAAA,GAUf,MAAA,CAAO,MAVQ,CAUD,gBAVC,CAUgB,CAVhB,CAAA,MAAA,CAAA,CAAA,CAAA;;;;AAKxE,cAcC,mBAdkB,EAcC,MAAA,CAAA,MAdD,CAAA;EAAW,SAAA,EAAA,eAAA;EAAoD,SAAA,IAAA,eAAA;EAAd,SAAA,QAAA,eAAA,cAAA,CAAA;EAAd,SAAO,GAAA,eAAA;EAAM,SAAA,IAAA,gBAAA;AAK/E,CAAA,CAAA;;;;;;AASA;;;;;;;;;AAwSA;;;;;;AACA;;AAAuE,iBADvD,WACuD,CAAA,UADjC,YACiC,CAAA,CAAA,SAAA,EADR,CACQ,CAAA,EADJ,WACI,CADQ,CACR,CAAA;AAAwB,iBAA/E,WAA+E,CAAA,UAAzD,oBAAyD,CAAA,CAAA,SAAA,EAAxB,CAAwB,CAAA,EAApB,mBAAoB,CAAA,CAAA,CAAA;;;AA0B/F;;;;;;AACA;;;;;;;;;;;;;iBADgB,yBAAyB,yBAAyB,IAAI,eAAe;iBACrE,yBAAyB,iCAAiC,IAAI,uBAAuB"}
@@ -26,11 +26,11 @@ type ToTreeNodeUpdateSchema<T extends AnyTreeNodePrimitive> = Schema.Schema<Infe
26
26
  * Schema for a tree node state (flat storage format).
27
27
  */
28
28
  declare const TreeNodeStateSchema: Schema.Struct<{
29
- id: typeof Schema.String;
30
- type: typeof Schema.String;
31
- parentId: Schema.NullOr<typeof Schema.String>;
32
- pos: typeof Schema.String;
33
- data: typeof Schema.Unknown;
29
+ readonly id: Schema.String;
30
+ readonly type: Schema.String;
31
+ readonly parentId: Schema.NullOr<Schema.String>;
32
+ readonly pos: Schema.String;
33
+ readonly data: Schema.Unknown;
34
34
  }>;
35
35
  /**
36
36
  * Convert a Mimic primitive to an Effect.Schema for set operations.
@@ -1 +1 @@
1
- {"version":3,"file":"EffectSchema.d.mts","names":[],"sources":["../src/EffectSchema.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;KAsBY,sBAAsB,gBAAgB,MAAA,CAAO,OAAO,cAAc;;;;AAAlE,KAKA,cALW,CAAA,UAKc,YALd,CAAA,GAK8B,MAAA,CAAO,MALrC,CAK4C,gBAL5C,CAK6D,CAL7D,CAAA,CAAA;;;;AAA2B,KAUtC,mBAV6C,CAAA,UAUf,oBAVe,CAAA,GAUS,MAAA,CAAO,MAVhB,CAUuB,aAVvB,CAUqC,CAVrC,CAAA,MAAA,CAAA,CAAA,CAAA;;AAKzD;;AAAoF,KAUxE,sBAVwE,CAAA,UAUvC,oBAVuC,CAAA,GAUf,MAAA,CAAO,MAVQ,CAUD,gBAVC,CAUgB,CAVhB,CAAA,MAAA,CAAA,CAAA,CAAA;;;;AAKxE,cAcC,mBAdkB,EAcC,MAAA,CAAA,MAdD,CAAA;EAAW,EAAA,EAAA,oBAAA;EAAoD,IAAA,EAAA,oBAAA;EAAd,QAAA,eAAA,CAAA,oBAAA,CAAA;EAAd,GAAA,EAAO,oBAAA;EAAM,IAAA,EAAA,qBAAA;AAK/E,CAAA,CAAA;;;;;;AASA;;;;;;;;;AAwSA;;;;;;AACA;;AAAuE,iBADvD,WACuD,CAAA,UADjC,YACiC,CAAA,CAAA,SAAA,EADR,CACQ,CAAA,EADJ,WACI,CADQ,CACR,CAAA;AAAwB,iBAA/E,WAA+E,CAAA,UAAzD,oBAAyD,CAAA,CAAA,SAAA,EAAxB,CAAwB,CAAA,EAApB,mBAAoB,CAAA,CAAA,CAAA;;;AA0B/F;;;;;;AACA;;;;;;;;;;;;;iBADgB,yBAAyB,yBAAyB,IAAI,eAAe;iBACrE,yBAAyB,iCAAiC,IAAI,uBAAuB"}
1
+ {"version":3,"file":"EffectSchema.d.mts","names":[],"sources":["../src/EffectSchema.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;KAsBY,sBAAsB,gBAAgB,MAAA,CAAO,OAAO,cAAc;;;;AAAlE,KAKA,cALW,CAAA,UAKc,YALd,CAAA,GAK8B,MAAA,CAAO,MALrC,CAK4C,gBAL5C,CAK6D,CAL7D,CAAA,CAAA;;;;AAA2B,KAUtC,mBAV6C,CAAA,UAUf,oBAVe,CAAA,GAUS,MAAA,CAAO,MAVhB,CAUuB,aAVvB,CAUqC,CAVrC,CAAA,MAAA,CAAA,CAAA,CAAA;;AAKzD;;AAAoF,KAUxE,sBAVwE,CAAA,UAUvC,oBAVuC,CAAA,GAUf,MAAA,CAAO,MAVQ,CAUD,gBAVC,CAUgB,CAVhB,CAAA,MAAA,CAAA,CAAA,CAAA;;;;AAKxE,cAcC,mBAdkB,EAcC,MAAA,CAAA,MAdD,CAAA;EAAW,SAAA,EAAA,eAAA;EAAoD,SAAA,IAAA,eAAA;EAAd,SAAA,QAAA,eAAA,cAAA,CAAA;EAAd,SAAO,GAAA,eAAA;EAAM,SAAA,IAAA,gBAAA;AAK/E,CAAA,CAAA;;;;;;AASA;;;;;;;;;AAwSA;;;;;;AACA;;AAAuE,iBADvD,WACuD,CAAA,UADjC,YACiC,CAAA,CAAA,SAAA,EADR,CACQ,CAAA,EADJ,WACI,CADQ,CACR,CAAA;AAAwB,iBAA/E,WAA+E,CAAA,UAAzD,oBAAyD,CAAA,CAAA,SAAA,EAAxB,CAAwB,CAAA,EAApB,mBAAoB,CAAA,CAAA,CAAA;;;AA0B/F;;;;;;AACA;;;;;;;;;;;;;iBADgB,yBAAyB,yBAAyB,IAAI,eAAe;iBACrE,yBAAyB,iCAAiC,IAAI,uBAAuB"}
@@ -117,7 +117,7 @@ function buildUnionSetSchema(unionPrimitive) {
117
117
  }
118
118
  if (variantSchemas.length === 0) return Schema.Unknown;
119
119
  if (variantSchemas.length === 1) return variantSchemas[0];
120
- return Schema.Union(...variantSchemas);
120
+ return Schema.Union(variantSchemas);
121
121
  }
122
122
  /**
123
123
  * Build the schema for an either primitive.
@@ -129,7 +129,7 @@ function buildEitherSchema(eitherPrimitive) {
129
129
  for (const variant of variants) variantSchemas.push(getBaseSchema(variant));
130
130
  if (variantSchemas.length === 0) return Schema.Unknown;
131
131
  if (variantSchemas.length === 1) return variantSchemas[0];
132
- return Schema.Union(...variantSchemas);
132
+ return Schema.Union(variantSchemas);
133
133
  }
134
134
  /**
135
135
  * Build the update schema for a union primitive.
@@ -144,7 +144,7 @@ function buildUnionUpdateSchema(unionPrimitive) {
144
144
  }
145
145
  if (variantSchemas.length === 0) return Schema.Unknown;
146
146
  if (variantSchemas.length === 1) return variantSchemas[0];
147
- return Schema.Union(...variantSchemas);
147
+ return Schema.Union(variantSchemas);
148
148
  }
149
149
  /**
150
150
  * Get the update schema for a primitive.
@@ -1 +1 @@
1
- {"version":3,"file":"EffectSchema.mjs","names":["schemaFields: Record<string, any>","fieldSchema: Schema.Schema<any>","variantSchemas: Schema.Schema<any>[]"],"sources":["../src/EffectSchema.ts"],"sourcesContent":["/**\n * Effect.Schema utilities for converting Mimic primitives to Effect.Schema schemas.\n * \n * @since 0.0.1\n */\nimport { Schema } from \"effect\";\nimport type { AnyPrimitive, InferSetInput, InferUpdateInput } from \"./primitives/shared\";\nimport type { LiteralPrimitive, LiteralValue } from \"./primitives/Literal\";\nimport type { StructPrimitive } from \"./primitives/Struct\";\nimport type { ArrayPrimitive } from \"./primitives/Array\";\nimport type { UnionPrimitive, UnionVariants } from \"./primitives/Union\";\nimport type { EitherPrimitive, ScalarPrimitive } from \"./primitives/Either\";\nimport type { LazyPrimitive } from \"./primitives/Lazy\";\nimport type { TreeNodePrimitive, AnyTreeNodePrimitive } from \"./primitives/TreeNode\";\n\n// =============================================================================\n// Type-level Schema Inference\n// =============================================================================\n\n/**\n * Infer the Effect.Schema type for a primitive's set input.\n */\nexport type ToSetSchema<T extends AnyPrimitive> = Schema.Schema<InferSetInput<T>>;\n\n/**\n * Infer the Effect.Schema type for a primitive's update input.\n */\nexport type ToUpdateSchema<T extends AnyPrimitive> = Schema.Schema<InferUpdateInput<T>>;\n\n/**\n * Type for TreeNode set schema - uses the node's data set input type\n */\nexport type ToTreeNodeSetSchema<T extends AnyTreeNodePrimitive> = Schema.Schema<InferSetInput<T[\"data\"]>>;\n\n/**\n * Type for TreeNode update schema - uses the node's data update input type\n */\nexport type ToTreeNodeUpdateSchema<T extends AnyTreeNodePrimitive> = Schema.Schema<InferUpdateInput<T[\"data\"]>>;\n\n// =============================================================================\n// Schema for TreeNodeState\n// =============================================================================\n\n/**\n * Schema for a tree node state (flat storage format).\n */\nexport const TreeNodeStateSchema = Schema.Struct({\n id: Schema.String,\n type: Schema.String,\n parentId: Schema.NullOr(Schema.String),\n pos: Schema.String,\n data: Schema.Unknown,\n});\n\n// =============================================================================\n// Internal type for primitives (including those that don't implement full Primitive interface)\n// =============================================================================\n\n/**\n * Internal type for anything that can be converted to a schema.\n * This includes both AnyPrimitive and AnyTreeNodePrimitive.\n */\ntype ConvertiblePrimitive = { _tag: string };\n\n// =============================================================================\n// Runtime Conversion Functions\n// =============================================================================\n\n/**\n * Check if a field is required for set operations.\n * A field is required if: TRequired is true AND THasDefault is false.\n * \n * We determine this by checking the primitive's schema properties.\n */\nfunction isRequiredForSet(primitive: ConvertiblePrimitive): boolean {\n // Access the private schema to check required and default status\n const schema = (primitive as any)._schema;\n if (!schema) return false;\n \n return schema.required === true && schema.defaultValue === undefined;\n}\n\n/**\n * Get the base Effect.Schema for a primitive type (without optional wrapper).\n */\nfunction getBaseSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n switch (primitive._tag) {\n case \"StringPrimitive\":\n return Schema.String;\n \n case \"NumberPrimitive\":\n return Schema.Number;\n \n case \"BooleanPrimitive\":\n return Schema.Boolean;\n \n case \"LiteralPrimitive\": {\n const literalPrimitive = primitive as unknown as LiteralPrimitive<LiteralValue, any, any>;\n const literalValue = (literalPrimitive as any)._schema?.literal ?? (literalPrimitive as any).literal;\n return Schema.Literal(literalValue);\n }\n \n case \"StructPrimitive\": {\n const structPrimitive = primitive as unknown as StructPrimitive<Record<string, AnyPrimitive>, any, any>;\n return buildStructSetSchema(structPrimitive);\n }\n \n case \"ArrayPrimitive\": {\n const arrayPrimitive = primitive as unknown as ArrayPrimitive<AnyPrimitive, any, any>;\n const elementSchema = buildElementSetSchema(arrayPrimitive.element);\n return Schema.Array(elementSchema);\n }\n \n case \"UnionPrimitive\": {\n const unionPrimitive = primitive as unknown as UnionPrimitive<UnionVariants, any, any, any>;\n return buildUnionSetSchema(unionPrimitive);\n }\n \n case \"EitherPrimitive\": {\n const eitherPrimitive = primitive as unknown as EitherPrimitive<readonly ScalarPrimitive[], any, any>;\n return buildEitherSchema(eitherPrimitive);\n }\n \n case \"LazyPrimitive\": {\n const lazyPrimitive = primitive as unknown as LazyPrimitive<() => AnyPrimitive>;\n // Resolve the lazy primitive and get its schema\n const resolved = (lazyPrimitive as any)._resolve?.() ?? (lazyPrimitive as any)._thunk();\n return getBaseSchema(resolved);\n }\n \n case \"TreeNodePrimitive\": {\n const treeNodePrimitive = primitive as unknown as TreeNodePrimitive<string, StructPrimitive<any>, any>;\n // TreeNode delegates to its data struct\n return buildStructSetSchema(treeNodePrimitive.data);\n }\n \n case \"TreePrimitive\": {\n // Tree returns an array of TreeNodeState\n return Schema.Array(TreeNodeStateSchema);\n }\n \n default:\n return Schema.Unknown;\n }\n}\n\n/**\n * Build the set schema for a struct primitive.\n * Required fields (required=true, no default) are non-optional.\n * Other fields are wrapped with Schema.optional.\n */\nfunction buildStructSetSchema(structPrimitive: StructPrimitive<Record<string, AnyPrimitive>, any, any>): Schema.Schema<any> {\n const fields = structPrimitive.fields;\n // Use any to avoid complex Schema type constraints\n const schemaFields: Record<string, any> = {};\n \n for (const key in fields) {\n const fieldPrimitive = fields[key]!;\n const baseSchema = getBaseSchema(fieldPrimitive);\n \n if (isRequiredForSet(fieldPrimitive)) {\n // Required field - use base schema directly\n schemaFields[key] = baseSchema;\n } else {\n // Optional field - wrap with Schema.optional\n schemaFields[key] = Schema.optional(baseSchema);\n }\n }\n \n return Schema.Struct(schemaFields) as any;\n}\n\n/**\n * Build the update schema for a struct primitive.\n * All fields are optional for partial updates.\n */\nfunction buildStructUpdateSchema(structPrimitive: StructPrimitive<Record<string, AnyPrimitive>, any, any>): Schema.Schema<any> {\n const fields = structPrimitive.fields;\n // Use any to avoid complex Schema type constraints\n const schemaFields: Record<string, any> = {};\n \n for (const key in fields) {\n const fieldPrimitive = fields[key]!;\n // For update, use the update schema for nested structs, otherwise base schema\n let fieldSchema: Schema.Schema<any>;\n \n if (fieldPrimitive._tag === \"StructPrimitive\") {\n fieldSchema = buildStructUpdateSchema(fieldPrimitive as StructPrimitive<Record<string, AnyPrimitive>, any, any>);\n } else {\n fieldSchema = getBaseSchema(fieldPrimitive);\n }\n \n // All fields are optional in update\n schemaFields[key] = Schema.optional(fieldSchema);\n }\n \n return Schema.Struct(schemaFields) as any;\n}\n\n/**\n * Build the set schema for an array element.\n * For struct elements, uses the struct's set input schema.\n */\nfunction buildElementSetSchema(elementPrimitive: AnyPrimitive): Schema.Schema<any> {\n if (elementPrimitive._tag === \"StructPrimitive\") {\n return buildStructSetSchema(elementPrimitive as StructPrimitive<Record<string, AnyPrimitive>, any, any>);\n }\n return getBaseSchema(elementPrimitive);\n}\n\n/**\n * Build the set schema for a union primitive.\n * Creates a Schema.Union of all variant schemas.\n */\nfunction buildUnionSetSchema(unionPrimitive: UnionPrimitive<UnionVariants, any, any, any>): Schema.Schema<any> {\n const variants = unionPrimitive.variants;\n const variantSchemas: Schema.Schema<any>[] = [];\n \n for (const key in variants) {\n const variantPrimitive = variants[key]!;\n variantSchemas.push(buildStructSetSchema(variantPrimitive));\n }\n \n if (variantSchemas.length === 0) {\n return Schema.Unknown;\n }\n \n if (variantSchemas.length === 1) {\n return variantSchemas[0]!;\n }\n \n return Schema.Union(...variantSchemas as [Schema.Schema<any>, Schema.Schema<any>, ...Schema.Schema<any>[]]);\n}\n\n/**\n * Build the schema for an either primitive.\n * Creates a Schema.Union of all scalar variant types.\n */\nfunction buildEitherSchema(eitherPrimitive: EitherPrimitive<readonly ScalarPrimitive[], any, any>): Schema.Schema<any> {\n const variants = eitherPrimitive.variants;\n const variantSchemas: Schema.Schema<any>[] = [];\n \n for (const variant of variants) {\n variantSchemas.push(getBaseSchema(variant as unknown as ConvertiblePrimitive));\n }\n \n if (variantSchemas.length === 0) {\n return Schema.Unknown;\n }\n \n if (variantSchemas.length === 1) {\n return variantSchemas[0]!;\n }\n \n return Schema.Union(...variantSchemas as [Schema.Schema<any>, Schema.Schema<any>, ...Schema.Schema<any>[]]);\n}\n\n/**\n * Build the update schema for a union primitive.\n * Creates a Schema.Union of all variant update schemas.\n */\nfunction buildUnionUpdateSchema(unionPrimitive: UnionPrimitive<UnionVariants, any, any, any>): Schema.Schema<any> {\n const variants = unionPrimitive.variants;\n const variantSchemas: Schema.Schema<any>[] = [];\n \n for (const key in variants) {\n const variantPrimitive = variants[key]!;\n variantSchemas.push(buildStructUpdateSchema(variantPrimitive));\n }\n \n if (variantSchemas.length === 0) {\n return Schema.Unknown;\n }\n \n if (variantSchemas.length === 1) {\n return variantSchemas[0]!;\n }\n \n return Schema.Union(...variantSchemas as [Schema.Schema<any>, Schema.Schema<any>, ...Schema.Schema<any>[]]);\n}\n\n/**\n * Get the update schema for a primitive.\n * For structs, all fields are optional (partial updates).\n * For simple primitives, same as set schema.\n */\nfunction getUpdateSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n switch (primitive._tag) {\n case \"StructPrimitive\": {\n const structPrimitive = primitive as unknown as StructPrimitive<Record<string, AnyPrimitive>, any, any>;\n return buildStructUpdateSchema(structPrimitive);\n }\n \n case \"UnionPrimitive\": {\n const unionPrimitive = primitive as unknown as UnionPrimitive<UnionVariants, any, any, any>;\n return buildUnionUpdateSchema(unionPrimitive);\n }\n \n case \"TreeNodePrimitive\": {\n const treeNodePrimitive = primitive as unknown as TreeNodePrimitive<string, StructPrimitive<any>, any>;\n // TreeNode update delegates to data struct's update schema (all fields optional)\n return buildStructUpdateSchema(treeNodePrimitive.data);\n }\n \n case \"LazyPrimitive\": {\n const lazyPrimitive = primitive as unknown as LazyPrimitive<() => AnyPrimitive>;\n const resolved = (lazyPrimitive as any)._resolve?.() ?? (lazyPrimitive as any)._thunk();\n return getUpdateSchema(resolved);\n }\n \n default:\n // For simple primitives, update schema is same as set schema\n return getBaseSchema(primitive);\n }\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Convert a Mimic primitive to an Effect.Schema for set operations.\n * \n * The resulting schema:\n * - For structs: required fields (required=true, no default) are non-optional, others are optional\n * - For arrays: uses the element's set schema\n * - For unions: creates a Schema.Union of variant schemas\n * - For TreeNode: delegates to the node's data struct schema\n * - For Tree: returns Schema.Array of TreeNodeState\n * \n * @example\n * ```typescript\n * const UserSchema = Primitive.Struct({\n * name: Primitive.String().required(),\n * age: Primitive.Number().default(0),\n * email: Primitive.String(),\n * });\n * \n * const SetSchema = toSetSchema(UserSchema);\n * // { name: string, age?: number, email?: string }\n * ```\n */\nexport function toSetSchema<T extends AnyPrimitive>(primitive: T): ToSetSchema<T>;\nexport function toSetSchema<T extends AnyTreeNodePrimitive>(primitive: T): ToTreeNodeSetSchema<T>;\nexport function toSetSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n return getBaseSchema(primitive);\n}\n\n/**\n * Convert a Mimic primitive to an Effect.Schema for update operations.\n * \n * The resulting schema:\n * - For structs: all fields are optional (partial updates)\n * - For unions: all variant fields are optional\n * - For TreeNode: delegates to the node's data struct update schema\n * - For simple primitives: same as set schema\n * \n * @example\n * ```typescript\n * const UserSchema = Primitive.Struct({\n * name: Primitive.String().required(),\n * age: Primitive.Number().default(0),\n * email: Primitive.String(),\n * });\n * \n * const UpdateSchema = toUpdateSchema(UserSchema);\n * // { name?: string, age?: string, email?: string }\n * ```\n */\nexport function toUpdateSchema<T extends AnyPrimitive>(primitive: T): ToUpdateSchema<T>;\nexport function toUpdateSchema<T extends AnyTreeNodePrimitive>(primitive: T): ToTreeNodeUpdateSchema<T>;\nexport function toUpdateSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n return getUpdateSchema(primitive);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EffectSchema.mjs","names":["schemaFields: Record<string, any>","fieldSchema: Schema.Schema<any>","variantSchemas: Schema.Schema<any>[]"],"sources":["../src/EffectSchema.ts"],"sourcesContent":["/**\n * Effect.Schema utilities for converting Mimic primitives to Effect.Schema schemas.\n * \n * @since 0.0.1\n */\nimport { Schema } from \"effect\";\nimport type { AnyPrimitive, InferSetInput, InferUpdateInput } from \"./primitives/shared\";\nimport type { LiteralPrimitive, LiteralValue } from \"./primitives/Literal\";\nimport type { StructPrimitive } from \"./primitives/Struct\";\nimport type { ArrayPrimitive } from \"./primitives/Array\";\nimport type { UnionPrimitive, UnionVariants } from \"./primitives/Union\";\nimport type { EitherPrimitive, ScalarPrimitive } from \"./primitives/Either\";\nimport type { LazyPrimitive } from \"./primitives/Lazy\";\nimport type { TreeNodePrimitive, AnyTreeNodePrimitive } from \"./primitives/TreeNode\";\n\n// =============================================================================\n// Type-level Schema Inference\n// =============================================================================\n\n/**\n * Infer the Effect.Schema type for a primitive's set input.\n */\nexport type ToSetSchema<T extends AnyPrimitive> = Schema.Schema<InferSetInput<T>>;\n\n/**\n * Infer the Effect.Schema type for a primitive's update input.\n */\nexport type ToUpdateSchema<T extends AnyPrimitive> = Schema.Schema<InferUpdateInput<T>>;\n\n/**\n * Type for TreeNode set schema - uses the node's data set input type\n */\nexport type ToTreeNodeSetSchema<T extends AnyTreeNodePrimitive> = Schema.Schema<InferSetInput<T[\"data\"]>>;\n\n/**\n * Type for TreeNode update schema - uses the node's data update input type\n */\nexport type ToTreeNodeUpdateSchema<T extends AnyTreeNodePrimitive> = Schema.Schema<InferUpdateInput<T[\"data\"]>>;\n\n// =============================================================================\n// Schema for TreeNodeState\n// =============================================================================\n\n/**\n * Schema for a tree node state (flat storage format).\n */\nexport const TreeNodeStateSchema = Schema.Struct({\n id: Schema.String,\n type: Schema.String,\n parentId: Schema.NullOr(Schema.String),\n pos: Schema.String,\n data: Schema.Unknown,\n});\n\n// =============================================================================\n// Internal type for primitives (including those that don't implement full Primitive interface)\n// =============================================================================\n\n/**\n * Internal type for anything that can be converted to a schema.\n * This includes both AnyPrimitive and AnyTreeNodePrimitive.\n */\ntype ConvertiblePrimitive = { _tag: string };\n\n// =============================================================================\n// Runtime Conversion Functions\n// =============================================================================\n\n/**\n * Check if a field is required for set operations.\n * A field is required if: TRequired is true AND THasDefault is false.\n * \n * We determine this by checking the primitive's schema properties.\n */\nfunction isRequiredForSet(primitive: ConvertiblePrimitive): boolean {\n // Access the private schema to check required and default status\n const schema = (primitive as any)._schema;\n if (!schema) return false;\n \n return schema.required === true && schema.defaultValue === undefined;\n}\n\n/**\n * Get the base Effect.Schema for a primitive type (without optional wrapper).\n */\nfunction getBaseSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n switch (primitive._tag) {\n case \"StringPrimitive\":\n return Schema.String;\n \n case \"NumberPrimitive\":\n return Schema.Number;\n \n case \"BooleanPrimitive\":\n return Schema.Boolean;\n \n case \"LiteralPrimitive\": {\n const literalPrimitive = primitive as unknown as LiteralPrimitive<LiteralValue, any, any>;\n const literalValue = (literalPrimitive as any)._schema?.literal ?? (literalPrimitive as any).literal;\n return Schema.Literal(literalValue);\n }\n \n case \"StructPrimitive\": {\n const structPrimitive = primitive as unknown as StructPrimitive<Record<string, AnyPrimitive>, any, any>;\n return buildStructSetSchema(structPrimitive);\n }\n \n case \"ArrayPrimitive\": {\n const arrayPrimitive = primitive as unknown as ArrayPrimitive<AnyPrimitive, any, any>;\n const elementSchema = buildElementSetSchema(arrayPrimitive.element);\n return Schema.Array(elementSchema);\n }\n \n case \"UnionPrimitive\": {\n const unionPrimitive = primitive as unknown as UnionPrimitive<UnionVariants, any, any, any>;\n return buildUnionSetSchema(unionPrimitive);\n }\n \n case \"EitherPrimitive\": {\n const eitherPrimitive = primitive as unknown as EitherPrimitive<readonly ScalarPrimitive[], any, any>;\n return buildEitherSchema(eitherPrimitive);\n }\n \n case \"LazyPrimitive\": {\n const lazyPrimitive = primitive as unknown as LazyPrimitive<() => AnyPrimitive>;\n // Resolve the lazy primitive and get its schema\n const resolved = (lazyPrimitive as any)._resolve?.() ?? (lazyPrimitive as any)._thunk();\n return getBaseSchema(resolved);\n }\n \n case \"TreeNodePrimitive\": {\n const treeNodePrimitive = primitive as unknown as TreeNodePrimitive<string, StructPrimitive<any>, any>;\n // TreeNode delegates to its data struct\n return buildStructSetSchema(treeNodePrimitive.data);\n }\n \n case \"TreePrimitive\": {\n // Tree returns an array of TreeNodeState\n return Schema.Array(TreeNodeStateSchema);\n }\n \n default:\n return Schema.Unknown;\n }\n}\n\n/**\n * Build the set schema for a struct primitive.\n * Required fields (required=true, no default) are non-optional.\n * Other fields are wrapped with Schema.optional.\n */\nfunction buildStructSetSchema(structPrimitive: StructPrimitive<Record<string, AnyPrimitive>, any, any>): Schema.Schema<any> {\n const fields = structPrimitive.fields;\n // Use any to avoid complex Schema type constraints\n const schemaFields: Record<string, any> = {};\n \n for (const key in fields) {\n const fieldPrimitive = fields[key]!;\n const baseSchema = getBaseSchema(fieldPrimitive);\n \n if (isRequiredForSet(fieldPrimitive)) {\n // Required field - use base schema directly\n schemaFields[key] = baseSchema;\n } else {\n // Optional field - wrap with Schema.optional\n schemaFields[key] = Schema.optional(baseSchema);\n }\n }\n \n return Schema.Struct(schemaFields) as any;\n}\n\n/**\n * Build the update schema for a struct primitive.\n * All fields are optional for partial updates.\n */\nfunction buildStructUpdateSchema(structPrimitive: StructPrimitive<Record<string, AnyPrimitive>, any, any>): Schema.Schema<any> {\n const fields = structPrimitive.fields;\n // Use any to avoid complex Schema type constraints\n const schemaFields: Record<string, any> = {};\n \n for (const key in fields) {\n const fieldPrimitive = fields[key]!;\n // For update, use the update schema for nested structs, otherwise base schema\n let fieldSchema: Schema.Schema<any>;\n \n if (fieldPrimitive._tag === \"StructPrimitive\") {\n fieldSchema = buildStructUpdateSchema(fieldPrimitive as StructPrimitive<Record<string, AnyPrimitive>, any, any>);\n } else {\n fieldSchema = getBaseSchema(fieldPrimitive);\n }\n \n // All fields are optional in update\n schemaFields[key] = Schema.optional(fieldSchema);\n }\n \n return Schema.Struct(schemaFields) as any;\n}\n\n/**\n * Build the set schema for an array element.\n * For struct elements, uses the struct's set input schema.\n */\nfunction buildElementSetSchema(elementPrimitive: AnyPrimitive): Schema.Schema<any> {\n if (elementPrimitive._tag === \"StructPrimitive\") {\n return buildStructSetSchema(elementPrimitive as StructPrimitive<Record<string, AnyPrimitive>, any, any>);\n }\n return getBaseSchema(elementPrimitive);\n}\n\n/**\n * Build the set schema for a union primitive.\n * Creates a Schema.Union of all variant schemas.\n */\nfunction buildUnionSetSchema(unionPrimitive: UnionPrimitive<UnionVariants, any, any, any>): Schema.Schema<any> {\n const variants = unionPrimitive.variants;\n const variantSchemas: Schema.Schema<any>[] = [];\n \n for (const key in variants) {\n const variantPrimitive = variants[key]!;\n variantSchemas.push(buildStructSetSchema(variantPrimitive));\n }\n \n if (variantSchemas.length === 0) {\n return Schema.Unknown;\n }\n \n if (variantSchemas.length === 1) {\n return variantSchemas[0]!;\n }\n \n return Schema.Union(variantSchemas as any);\n}\n\n/**\n * Build the schema for an either primitive.\n * Creates a Schema.Union of all scalar variant types.\n */\nfunction buildEitherSchema(eitherPrimitive: EitherPrimitive<readonly ScalarPrimitive[], any, any>): Schema.Schema<any> {\n const variants = eitherPrimitive.variants;\n const variantSchemas: Schema.Schema<any>[] = [];\n \n for (const variant of variants) {\n variantSchemas.push(getBaseSchema(variant as unknown as ConvertiblePrimitive));\n }\n \n if (variantSchemas.length === 0) {\n return Schema.Unknown;\n }\n \n if (variantSchemas.length === 1) {\n return variantSchemas[0]!;\n }\n \n return Schema.Union(variantSchemas as any);\n}\n\n/**\n * Build the update schema for a union primitive.\n * Creates a Schema.Union of all variant update schemas.\n */\nfunction buildUnionUpdateSchema(unionPrimitive: UnionPrimitive<UnionVariants, any, any, any>): Schema.Schema<any> {\n const variants = unionPrimitive.variants;\n const variantSchemas: Schema.Schema<any>[] = [];\n \n for (const key in variants) {\n const variantPrimitive = variants[key]!;\n variantSchemas.push(buildStructUpdateSchema(variantPrimitive));\n }\n \n if (variantSchemas.length === 0) {\n return Schema.Unknown;\n }\n \n if (variantSchemas.length === 1) {\n return variantSchemas[0]!;\n }\n \n return Schema.Union(variantSchemas as any);\n}\n\n/**\n * Get the update schema for a primitive.\n * For structs, all fields are optional (partial updates).\n * For simple primitives, same as set schema.\n */\nfunction getUpdateSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n switch (primitive._tag) {\n case \"StructPrimitive\": {\n const structPrimitive = primitive as unknown as StructPrimitive<Record<string, AnyPrimitive>, any, any>;\n return buildStructUpdateSchema(structPrimitive);\n }\n \n case \"UnionPrimitive\": {\n const unionPrimitive = primitive as unknown as UnionPrimitive<UnionVariants, any, any, any>;\n return buildUnionUpdateSchema(unionPrimitive);\n }\n \n case \"TreeNodePrimitive\": {\n const treeNodePrimitive = primitive as unknown as TreeNodePrimitive<string, StructPrimitive<any>, any>;\n // TreeNode update delegates to data struct's update schema (all fields optional)\n return buildStructUpdateSchema(treeNodePrimitive.data);\n }\n \n case \"LazyPrimitive\": {\n const lazyPrimitive = primitive as unknown as LazyPrimitive<() => AnyPrimitive>;\n const resolved = (lazyPrimitive as any)._resolve?.() ?? (lazyPrimitive as any)._thunk();\n return getUpdateSchema(resolved);\n }\n \n default:\n // For simple primitives, update schema is same as set schema\n return getBaseSchema(primitive);\n }\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Convert a Mimic primitive to an Effect.Schema for set operations.\n * \n * The resulting schema:\n * - For structs: required fields (required=true, no default) are non-optional, others are optional\n * - For arrays: uses the element's set schema\n * - For unions: creates a Schema.Union of variant schemas\n * - For TreeNode: delegates to the node's data struct schema\n * - For Tree: returns Schema.Array of TreeNodeState\n * \n * @example\n * ```typescript\n * const UserSchema = Primitive.Struct({\n * name: Primitive.String().required(),\n * age: Primitive.Number().default(0),\n * email: Primitive.String(),\n * });\n * \n * const SetSchema = toSetSchema(UserSchema);\n * // { name: string, age?: number, email?: string }\n * ```\n */\nexport function toSetSchema<T extends AnyPrimitive>(primitive: T): ToSetSchema<T>;\nexport function toSetSchema<T extends AnyTreeNodePrimitive>(primitive: T): ToTreeNodeSetSchema<T>;\nexport function toSetSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n return getBaseSchema(primitive);\n}\n\n/**\n * Convert a Mimic primitive to an Effect.Schema for update operations.\n * \n * The resulting schema:\n * - For structs: all fields are optional (partial updates)\n * - For unions: all variant fields are optional\n * - For TreeNode: delegates to the node's data struct update schema\n * - For simple primitives: same as set schema\n * \n * @example\n * ```typescript\n * const UserSchema = Primitive.Struct({\n * name: Primitive.String().required(),\n * age: Primitive.Number().default(0),\n * email: Primitive.String(),\n * });\n * \n * const UpdateSchema = toUpdateSchema(UserSchema);\n * // { name?: string, age?: string, email?: string }\n * ```\n */\nexport function toUpdateSchema<T extends AnyPrimitive>(primitive: T): ToUpdateSchema<T>;\nexport function toUpdateSchema<T extends AnyTreeNodePrimitive>(primitive: T): ToTreeNodeUpdateSchema<T>;\nexport function toUpdateSchema(primitive: ConvertiblePrimitive): Schema.Schema<any> {\n return getUpdateSchema(primitive);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FractionalIndex.mjs","names":["byCode: Record<number, string>","byChar: Record<string, number>","paddingDict: Record<number, number>","paddingDict","_base62CharSet: IndexedCharacterSet | null","result: string[]"],"sources":["../src/FractionalIndex.ts"],"sourcesContent":["import { Effect, Random } from \"effect\"\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\nexport interface IndexCharacterSetOptions {\n chars: string // sorted string of unique characters like \"0123456789ABC\"\n jitterRange?: number // default is 1/5 of the total range created by adding 3 characters\n firstPositive?: string // default is the middle character\n mostPositive?: string // default is the last character\n mostNegative?: string // default is the first character\n}\n\nexport interface IndexedCharacterSet {\n chars: string\n byChar: Record<string, number>\n byCode: Record<number, string>\n paddingDict: Record<number, number>\n length: number\n first: string\n last: string\n firstPositive: string\n mostPositive: string\n firstNegative: string\n mostNegative: string\n jitterRange: number\n}\n\nexport type IntegerLimits = {\n firstPositive: string\n mostPositive: string\n firstNegative: string\n mostNegative: string\n}\n\nexport interface GeneratorOptions {\n charSet?: IndexedCharacterSet\n useJitter?: boolean\n groupIdLength?: number\n}\n\n// ============================================================================\n// Character Set Functions\n// ============================================================================\n\ntype CharSetDicts = {\n byCode: Record<number, string>\n byChar: Record<string, number>\n length: number\n}\n\nfunction createCharSetDicts(charSet: string): CharSetDicts {\n const byCode: Record<number, string> = {}\n const byChar: Record<string, number> = {}\n const length = charSet.length\n\n for (let i = 0; i < length; i++) {\n const char = charSet[i]\n if (char === undefined) {\n throw new Error(\"invalid charSet: missing character at index \" + i)\n }\n byCode[i] = char\n byChar[char] = i\n }\n return {\n byCode: byCode,\n byChar: byChar,\n length: length,\n }\n}\n\nfunction integerLimits(\n dicts: CharSetDicts,\n firstPositive?: string,\n mostPositive?: string,\n mostNegative?: string\n): Effect.Effect<IntegerLimits, Error> {\n return Effect.gen(function* () {\n const firstPositiveIndex = firstPositive\n ? dicts.byChar[firstPositive]\n : Math.ceil(dicts.length / 2)\n const mostPositiveIndex = mostPositive\n ? dicts.byChar[mostPositive]\n : dicts.length - 1\n const mostNegativeIndex = mostNegative ? dicts.byChar[mostNegative] : 0\n\n if (\n firstPositiveIndex === undefined ||\n mostPositiveIndex === undefined ||\n mostNegativeIndex === undefined\n ) {\n return yield* Effect.fail(new Error(\"invalid charSet\"))\n }\n if (mostPositiveIndex - firstPositiveIndex < 3) {\n return yield* Effect.fail(\n new Error(\"mostPositive must be at least 3 characters away from neutral\")\n )\n }\n if (firstPositiveIndex - mostNegativeIndex < 3) {\n return yield* Effect.fail(\n new Error(\"mostNegative must be at least 3 characters away from neutral\")\n )\n }\n\n const firstPositiveChar = dicts.byCode[firstPositiveIndex]\n const mostPositiveChar = dicts.byCode[mostPositiveIndex]\n const firstNegativeChar = dicts.byCode[firstPositiveIndex - 1]\n const mostNegativeChar = dicts.byCode[mostNegativeIndex]\n\n if (\n firstPositiveChar === undefined ||\n mostPositiveChar === undefined ||\n firstNegativeChar === undefined ||\n mostNegativeChar === undefined\n ) {\n return yield* Effect.fail(new Error(\"invalid charSet\"))\n }\n\n return {\n firstPositive: firstPositiveChar,\n mostPositive: mostPositiveChar,\n firstNegative: firstNegativeChar,\n mostNegative: mostNegativeChar,\n }\n })\n}\n\nfunction paddingDict(jitterRange: number, charSetLength: number): Record<number, number> {\n const paddingDict: Record<number, number> = {}\n for (let i = 0; i < 100; i++) {\n const value = Math.pow(charSetLength, i)\n paddingDict[i] = value\n if (value > jitterRange) {\n break\n }\n }\n return paddingDict\n}\n\nexport function validateChars(characters: string): Effect.Effect<void, Error> {\n if (characters.length < 7) {\n return Effect.fail(new Error(\"charSet must be at least 7 characters long\"))\n }\n const chars = characters.split(\"\")\n const sorted = chars.sort()\n const isEqual = sorted.join(\"\") === characters\n if (!isEqual) {\n return Effect.fail(new Error(\"charSet must be sorted\"))\n }\n return Effect.void\n}\n\nexport function indexCharacterSet(\n options: IndexCharacterSetOptions\n): Effect.Effect<IndexedCharacterSet, Error> {\n return Effect.gen(function* () {\n yield* validateChars(options.chars)\n const dicts = createCharSetDicts(options.chars)\n const limits = yield* integerLimits(\n dicts,\n options.firstPositive,\n options.mostPositive,\n options.mostNegative\n )\n // 1/5 of the total range if we add 3 characters, TODO: feels a bit arbitrary and could be improved\n const jitterRange =\n options.jitterRange ?? Math.floor(Math.pow(dicts.length, 3) / 5)\n\n const paddingRange = paddingDict(jitterRange, dicts.length)\n\n const first = dicts.byCode[0]\n const last = dicts.byCode[dicts.length - 1]\n\n if (first === undefined || last === undefined) {\n return yield* Effect.fail(new Error(\"invalid charSet\"))\n }\n\n return {\n chars: options.chars,\n byChar: dicts.byChar,\n byCode: dicts.byCode,\n length: dicts.length,\n first,\n last,\n firstPositive: limits.firstPositive,\n mostPositive: limits.mostPositive,\n firstNegative: limits.firstNegative,\n mostNegative: limits.mostNegative,\n jitterRange,\n paddingDict: paddingRange,\n }\n })\n}\n\n// cache the base62 charSet since it's the default\nlet _base62CharSet: IndexedCharacterSet | null = null\n\nexport function base62CharSet(): IndexedCharacterSet {\n if (_base62CharSet) return _base62CharSet\n // We use Effect.runSync here because base62CharSet is a synchronous API\n // and we know the parameters are valid\n _base62CharSet = Effect.runSync(\n indexCharacterSet({\n // Base62 are all the alphanumeric characters, database and user friendly\n // For shorter strings and more room you could opt for more characters\n chars: \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\",\n // This gives us nice human readable keys to start with a0 a1 etc\n firstPositive: \"a\",\n mostPositive: \"z\",\n mostNegative: \"A\",\n })\n )\n return _base62CharSet\n}\n\n// ============================================================================\n// Padding Functions\n// ============================================================================\n\nexport function makeSameLength(\n a: string,\n b: string,\n pad: \"start\" | \"end\",\n fillChar: string,\n forceLength?: number\n): [string, string] {\n const max = forceLength ?? Math.max(a.length, b.length)\n if (pad === \"start\") {\n return [a.padStart(max, fillChar), b.padStart(max, fillChar)]\n }\n return [a.padEnd(max, fillChar), b.padEnd(max, fillChar)]\n}\n\n// ============================================================================\n// Integer Length Functions\n// ============================================================================\n\nfunction distanceBetween(\n a: string,\n b: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n const indexA = charSet.byChar[a]\n const indexB = charSet.byChar[b]\n if (indexA === undefined || indexB === undefined) {\n return Effect.fail(new Error(\"invalid character in distance calculation\"))\n }\n return Effect.succeed(Math.abs(indexA - indexB))\n}\n\nfunction integerLengthFromSecondLevel(\n key: string,\n direction: \"positive\" | \"negative\",\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n if (key.length === 0) {\n return Effect.succeed(0)\n }\n const firstChar = key[0]\n if (!firstChar || firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) {\n return Effect.fail(new Error(\"invalid firstChar on key\"))\n }\n if (firstChar === charSet.mostPositive && direction === \"positive\") {\n return Effect.gen(function* () {\n const totalPositiveRoom = yield* distanceBetween(firstChar, charSet.mostNegative, charSet)\n const rest = yield* integerLengthFromSecondLevel(key.slice(1), direction, charSet)\n return totalPositiveRoom + 1 + rest\n })\n }\n if (firstChar === charSet.mostNegative && direction === \"negative\") {\n return Effect.gen(function* () {\n const totalNegativeRoom = yield* distanceBetween(firstChar, charSet.mostPositive, charSet)\n const rest = yield* integerLengthFromSecondLevel(key.slice(1), direction, charSet)\n return totalNegativeRoom + 1 + rest\n })\n }\n if (direction === \"positive\") {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.mostNegative, charSet)\n return dist + 2\n })\n } else {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.mostPositive, charSet)\n return dist + 2\n })\n }\n}\n\nexport function integerLength(\n head: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n if (head.length === 0) {\n return Effect.fail(new Error(\"head cannot be empty\"))\n }\n const firstChar = head[0]\n if (!firstChar || firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) {\n return Effect.fail(new Error(\"invalid firstChar on key\"))\n }\n if (firstChar === charSet.mostPositive) {\n return Effect.gen(function* () {\n const firstLevel = yield* distanceBetween(firstChar, charSet.firstPositive, charSet)\n const rest = yield* integerLengthFromSecondLevel(head.slice(1), \"positive\", charSet)\n return firstLevel + 1 + rest\n })\n }\n if (firstChar === charSet.mostNegative) {\n return Effect.gen(function* () {\n const firstLevel = yield* distanceBetween(firstChar, charSet.firstNegative, charSet)\n const rest = yield* integerLengthFromSecondLevel(head.slice(1), \"negative\", charSet)\n return firstLevel + 1 + rest\n })\n }\n const isPositiveRange = firstChar >= charSet.firstPositive\n if (isPositiveRange) {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.firstPositive, charSet)\n return dist + 2\n })\n } else {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.firstNegative, charSet)\n return dist + 2\n })\n }\n}\n\n// ============================================================================\n// Key as Number Functions\n// ============================================================================\n\nexport function encodeToCharSet(int: number, charSet: IndexedCharacterSet): Effect.Effect<string, Error> {\n if (int === 0) {\n const zero = charSet.byCode[0]\n if (zero === undefined) {\n return Effect.fail(new Error(\"invalid charSet: missing code 0\"))\n }\n return Effect.succeed(zero)\n }\n let res = \"\"\n const max = charSet.length\n while (int > 0) {\n const code = charSet.byCode[int % max]\n if (code === undefined) {\n return Effect.fail(new Error(\"invalid character code in encodeToCharSet\"))\n }\n res = code + res\n int = Math.floor(int / max)\n }\n return Effect.succeed(res)\n}\n\nexport function decodeCharSetToNumber(\n key: string,\n charSet: IndexedCharacterSet\n): number {\n let res = 0\n const length = key.length\n const max = charSet.length\n for (let i = 0; i < length; i++) {\n const char = key[i]\n if (char === undefined) {\n continue\n }\n const charIndex = charSet.byChar[char]\n if (charIndex === undefined) {\n continue\n }\n res += charIndex * Math.pow(max, length - i - 1)\n }\n return res\n}\n\nexport function addCharSetKeys(\n a: string,\n b: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n const base = charSet.length\n const [paddedA, paddedB] = makeSameLength(a, b, \"start\", charSet.first)\n\n const result: string[] = []\n let carry = 0\n\n // Iterate over the digits from right to left\n for (let i = paddedA.length - 1; i >= 0; i--) {\n const charA = paddedA[i]\n const charB = paddedB[i]\n if (!charA || !charB) {\n return Effect.fail(new Error(\"invalid character in addCharSetKeys\"))\n }\n const digitA = charSet.byChar[charA]\n const digitB = charSet.byChar[charB]\n if (digitA === undefined || digitB === undefined) {\n return Effect.fail(new Error(\"invalid character in addCharSetKeys\"))\n }\n const sum = digitA + digitB + carry\n carry = Math.floor(sum / base)\n const remainder = sum % base\n\n const codeChar = charSet.byCode[remainder]\n if (codeChar === undefined) {\n return Effect.fail(new Error(\"invalid character code in addCharSetKeys\"))\n }\n result.unshift(codeChar)\n }\n\n // If there's a carry left, add it to the result\n if (carry > 0) {\n const carryChar = charSet.byCode[carry]\n if (carryChar === undefined) {\n return Effect.fail(new Error(\"invalid carry character code\"))\n }\n result.unshift(carryChar)\n }\n\n return Effect.succeed(result.join(\"\"))\n}\n\nexport function subtractCharSetKeys(\n a: string,\n b: string,\n charSet: IndexedCharacterSet,\n stripLeadingZeros = true\n): Effect.Effect<string, Error> {\n const base = charSet.length\n const [paddedA, paddedB] = makeSameLength(a, b, \"start\", charSet.first)\n\n const result: string[] = []\n let borrow = 0\n\n // Iterate over the digits from right to left\n for (let i = paddedA.length - 1; i >= 0; i--) {\n const charA = paddedA[i]\n const charB = paddedB[i]\n if (!charA || !charB) {\n return Effect.fail(new Error(\"invalid character in subtractCharSetKeys\"))\n }\n let digitA = charSet.byChar[charA]\n const digitBValue = charSet.byChar[charB]\n if (digitA === undefined || digitBValue === undefined) {\n return Effect.fail(new Error(\"invalid character in subtractCharSetKeys\"))\n }\n const digitB = digitBValue + borrow\n\n // Handle borrowing\n if (digitA < digitB) {\n borrow = 1\n digitA += base\n } else {\n borrow = 0\n }\n\n const difference = digitA - digitB\n const codeChar = charSet.byCode[difference]\n if (codeChar === undefined) {\n return Effect.fail(new Error(\"invalid character code in subtractCharSetKeys\"))\n }\n result.unshift(codeChar)\n }\n\n // If there's a borrow left, we have a negative result, which is not supported\n if (borrow > 0) {\n return Effect.fail(\n new Error(\"Subtraction result is negative. Ensure a is greater than or equal to b.\")\n )\n }\n\n // Remove leading zeros\n while (\n stripLeadingZeros &&\n result.length > 1 &&\n result[0] === charSet.first\n ) {\n result.shift()\n }\n\n return Effect.succeed(result.join(\"\"))\n}\n\nexport function incrementKey(key: string, charSet: IndexedCharacterSet): Effect.Effect<string, Error> {\n const one = charSet.byCode[1]\n if (one === undefined) {\n return Effect.fail(new Error(\"invalid charSet: missing code 1\"))\n }\n return addCharSetKeys(key, one, charSet)\n}\n\nexport function decrementKey(key: string, charSet: IndexedCharacterSet): Effect.Effect<string, Error> {\n // we should not strip leading zeros here, this will break the sorting if the key already has leading zeros\n const one = charSet.byCode[1]\n if (one === undefined) {\n return Effect.fail(new Error(\"invalid charSet: missing code 1\"))\n }\n return subtractCharSetKeys(key, one, charSet, false)\n}\n\nexport function lexicalDistance(\n a: string,\n b: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n const [lower, upper] = makeSameLength(a, b, \"end\", charSet.first).sort()\n return Effect.gen(function* () {\n const distance = yield* subtractCharSetKeys(upper, lower, charSet)\n return decodeCharSetToNumber(distance, charSet)\n })\n}\n\nexport function midPoint(\n lower: string,\n upper: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n let [paddedLower, paddedUpper] = makeSameLength(\n lower,\n upper,\n \"end\",\n charSet.first\n )\n let distance = yield* lexicalDistance(paddedLower, paddedUpper, charSet)\n if (distance === 1) {\n // if the numbers are consecutive we need more padding\n paddedLower = paddedLower.padEnd(paddedLower.length + 1, charSet.first)\n // the new distance will always be the length of the charSet\n distance = charSet.length\n }\n const mid = yield* encodeToCharSet(Math.floor(distance / 2), charSet)\n return yield* addCharSetKeys(paddedLower, mid, charSet)\n })\n}\n\n// ============================================================================\n// Integer Functions\n// ============================================================================\n\nexport function startKey(charSet: IndexedCharacterSet): string {\n return charSet.firstPositive + charSet.byCode[0]\n}\n\nexport function validInteger(integer: string, charSet: IndexedCharacterSet): Effect.Effect<boolean, Error> {\n return Effect.gen(function* () {\n const length = yield* integerLength(integer, charSet)\n return length === integer.length\n })\n}\n\nexport function validateOrderKey(\n orderKey: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<void, Error> {\n return Effect.gen(function* () {\n yield* getIntegerPart(orderKey, charSet)\n })\n}\n\nexport function getIntegerPart(\n orderKey: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const head = integerHead(orderKey, charSet)\n const integerPartLength = yield* integerLength(head, charSet)\n if (integerPartLength > orderKey.length) {\n return yield* Effect.fail(new Error(\"invalid order key length: \" + orderKey))\n }\n return orderKey.slice(0, integerPartLength)\n })\n}\n\nfunction validateInteger(integer: string, charSet: IndexedCharacterSet): Effect.Effect<void, Error> {\n return Effect.gen(function* () {\n const isValid = yield* validInteger(integer, charSet)\n if (!isValid) {\n return yield* Effect.fail(new Error(\"invalid integer length: \" + integer))\n }\n })\n}\n\nexport function integerHead(integer: string, charSet: IntegerLimits): string {\n let i = 0\n if (integer[0] === charSet.mostPositive) {\n while (integer[i] === charSet.mostPositive) {\n i = i + 1\n }\n }\n if (integer[0] === charSet.mostNegative) {\n while (integer[i] === charSet.mostNegative) {\n i = i + 1\n }\n }\n return integer.slice(0, i + 1)\n}\n\nexport function splitInteger(\n integer: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<[string, string], Error> {\n return Effect.gen(function* () {\n // We need to get the limits from the charSet\n const head = integerHead(integer, {\n firstPositive: charSet.firstPositive,\n mostPositive: charSet.mostPositive,\n firstNegative: charSet.firstNegative,\n mostNegative: charSet.mostNegative,\n })\n const tail = integer.slice(head.length)\n return [head, tail] as [string, string]\n })\n}\n\nexport function incrementIntegerHead(\n head: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const inPositiveRange = head >= charSet.firstPositive\n const nextHead = yield* incrementKey(head, charSet)\n const headIsLimitMax = head[head.length - 1] === charSet.mostPositive\n const nextHeadIsLimitMax =\n nextHead[nextHead.length - 1] === charSet.mostPositive\n\n // we can not leave the head on the limit value, we have no way to know where the head ends\n if (inPositiveRange && nextHeadIsLimitMax) {\n return nextHead + charSet.mostNegative\n }\n // we are already at the limit of this level, so we need to go up a level\n if (!inPositiveRange && headIsLimitMax) {\n return head.slice(0, head.length - 1)\n }\n return nextHead\n })\n}\n\nexport function decrementIntegerHead(\n head: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const inPositiveRange = head >= charSet.firstPositive\n const headIsLimitMin = head[head.length - 1] === charSet.mostNegative\n if (inPositiveRange && headIsLimitMin) {\n const nextLevel = head.slice(0, head.length - 1)\n // we can not leave the head on the limit value, we have no way to know where the head ends\n // so we take one extra step down\n const decremented = yield* decrementKey(nextLevel, charSet)\n return decremented\n }\n\n if (!inPositiveRange && headIsLimitMin) {\n return head + charSet.mostPositive\n }\n\n return yield* decrementKey(head, charSet)\n })\n}\n\nfunction startOnNewHead(\n head: string,\n limit: \"upper\" | \"lower\",\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const newLength = yield* integerLength(head, charSet)\n const fillCharCode = limit === \"upper\" ? charSet.length - 1 : 0\n const fillChar = charSet.byCode[fillCharCode]\n if (fillChar === undefined) {\n return yield* Effect.fail(new Error(\"invalid fill character code\"))\n }\n return head + fillChar.repeat(newLength - head.length)\n })\n}\n\nexport function incrementInteger(\n integer: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n yield* validateInteger(integer, charSet)\n const [head, digs] = yield* splitInteger(integer, charSet)\n const maxChar = charSet.byCode[charSet.length - 1]\n if (maxChar === undefined) {\n return yield* Effect.fail(new Error(\"invalid charSet: missing max character\"))\n }\n const anyNonMaxedDigit = digs\n .split(\"\")\n .some((d) => d !== maxChar)\n\n // we have room to increment\n if (anyNonMaxedDigit) {\n const newDigits = yield* incrementKey(digs, charSet)\n return head + newDigits\n }\n const nextHead = yield* incrementIntegerHead(head, charSet)\n return yield* startOnNewHead(nextHead, \"lower\", charSet)\n })\n}\n\nexport function decrementInteger(\n integer: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n yield* validateInteger(integer, charSet)\n const [head, digs] = yield* splitInteger(integer, charSet)\n const minChar = charSet.byCode[0]\n if (minChar === undefined) {\n return yield* Effect.fail(new Error(\"invalid charSet: missing min character\"))\n }\n const anyNonLimitDigit = digs.split(\"\").some((d) => d !== minChar)\n\n // we have room to decrement\n if (anyNonLimitDigit) {\n const newDigits = yield* decrementKey(digs, charSet)\n return head + newDigits\n }\n const nextHead = yield* decrementIntegerHead(head, charSet)\n return yield* startOnNewHead(nextHead, \"upper\", charSet)\n })\n}\n\n// ============================================================================\n// Jittering Functions\n// ============================================================================\n\nexport function jitterString(\n orderKey: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error, Random.Random> {\n return Effect.gen(function* () {\n const randomValue = yield* Random.next\n const shift = yield* encodeToCharSet(\n Math.floor(randomValue * charSet.jitterRange),\n charSet\n )\n return yield* addCharSetKeys(orderKey, shift, charSet)\n })\n}\n\nexport function padAndJitterString(\n orderKey: string,\n numberOfChars: number,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error, Random.Random> {\n return Effect.gen(function* () {\n const paddedKey = orderKey.padEnd(\n orderKey.length + numberOfChars,\n charSet.first\n )\n return yield* jitterString(paddedKey, charSet)\n })\n}\n\nexport function paddingNeededForDistance(\n distance: number,\n charSet: IndexedCharacterSet\n): number {\n const gap = charSet.jitterRange - distance\n const firstBigger = Object.entries(charSet.paddingDict).find(\n ([_key, value]) => {\n return value > gap\n }\n )\n\n return firstBigger ? parseInt(firstBigger[0]) : 0\n}\n\nexport function paddingNeededForJitter(\n orderKey: string,\n b: string | null,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n return Effect.gen(function* () {\n const integer = yield* getIntegerPart(orderKey, charSet)\n const nextInteger = yield* incrementInteger(integer, charSet)\n let needed = 0\n if (b !== null) {\n const distanceToB = yield* lexicalDistance(orderKey, b, charSet)\n if (distanceToB < charSet.jitterRange + 1) {\n needed = Math.max(needed, paddingNeededForDistance(distanceToB, charSet))\n }\n }\n const distanceToNextInteger = yield* lexicalDistance(orderKey, nextInteger, charSet)\n if (distanceToNextInteger < charSet.jitterRange + 1) {\n needed = Math.max(\n needed,\n paddingNeededForDistance(distanceToNextInteger, charSet)\n )\n }\n\n return needed\n })\n}\n\n// ============================================================================\n// Key Generation Functions\n// ============================================================================\n\n/**\n * Generate a key between two other keys.\n * If either lower or upper is null, the key will be generated at the start or end of the list.\n */\nexport function generateKeyBetween(\n lower: string | null,\n upper: string | null,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n if (lower !== null) {\n yield* validateOrderKey(lower, charSet)\n }\n if (upper !== null) {\n yield* validateOrderKey(upper, charSet)\n }\n if (lower === null && upper === null) {\n return startKey(charSet)\n }\n if (lower === null) {\n const integer = yield* getIntegerPart(upper!, charSet)\n return yield* decrementInteger(integer, charSet)\n }\n if (upper === null) {\n const integer = yield* getIntegerPart(lower, charSet)\n return yield* incrementInteger(integer, charSet)\n }\n if (lower >= upper) {\n return yield* Effect.fail(new Error(lower + \" >= \" + upper))\n }\n return yield* midPoint(lower, upper, charSet)\n })\n}\n\ntype GenerateKeyBetweenFunc = (\n lower: string | null,\n upper: string | null,\n charSet?: IndexedCharacterSet\n) => Effect.Effect<string, Error>\n\ntype GenerateNKeysBetweenFunc = (\n lower: string | null,\n upper: string | null,\n n: number,\n charSet?: IndexedCharacterSet\n) => Effect.Effect<string[], Error>\n\nfunction spreadGeneratorResults(\n lower: string | null,\n upper: string | null,\n n: number,\n charSet: IndexedCharacterSet,\n generateKey: GenerateKeyBetweenFunc,\n generateNKeys: GenerateNKeysBetweenFunc\n): Effect.Effect<string[], Error> {\n if (n === 0) {\n return Effect.succeed([])\n }\n if (n === 1) {\n return generateKey(lower, upper, charSet).pipe(Effect.map((key) => [key]))\n }\n if (upper == null) {\n return Effect.gen(function* () {\n let newUpper = yield* generateKey(lower, upper, charSet)\n const result = [newUpper]\n for (let i = 0; i < n - 1; i++) {\n newUpper = yield* generateKey(newUpper, upper, charSet)\n result.push(newUpper)\n }\n return result\n })\n }\n if (lower == null) {\n return Effect.gen(function* () {\n let newLower = yield* generateKey(lower, upper, charSet)\n const result = [newLower]\n for (let i = 0; i < n - 1; i++) {\n newLower = yield* generateKey(lower, newLower, charSet)\n result.push(newLower)\n }\n result.reverse()\n return result\n })\n }\n return Effect.gen(function* () {\n const mid = Math.floor(n / 2)\n const midOrderKey = yield* generateKey(lower, upper, charSet)\n const leftKeys = yield* generateNKeys(lower, midOrderKey, mid, charSet)\n const rightKeys = yield* generateNKeys(midOrderKey, upper, n - mid - 1, charSet)\n return [...leftKeys, midOrderKey, ...rightKeys]\n })\n}\n\n/**\n * Generate any number of keys between two other keys.\n * If either lower or upper is null, the keys will be generated at the start or end of the list.\n */\nexport function generateNKeysBetween(\n a: string | null,\n b: string | null,\n n: number,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string[], Error> {\n return spreadGeneratorResults(\n a,\n b,\n n,\n charSet,\n (lower, upper, charSet = base62CharSet()) => generateKeyBetween(lower, upper, charSet),\n (lower, upper, n, charSet = base62CharSet()) => generateNKeysBetween(lower, upper, n, charSet)\n )\n}\n\n/**\n * Generate a key between two other keys with jitter.\n * If either lower or upper is null, the key will be generated at the start or end of the list.\n */\nexport function generateJitteredKeyBetween(\n lower: string | null,\n upper: string | null,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string, Error, Random.Random> {\n return Effect.gen(function* () {\n const key = yield* generateKeyBetween(lower, upper, charSet)\n const paddingNeeded = yield* paddingNeededForJitter(key, upper, charSet)\n if (paddingNeeded) {\n return yield* padAndJitterString(key, paddingNeeded, charSet)\n }\n return yield* jitterString(key, charSet)\n })\n}\n\n/**\n * Generate any number of keys between two other keys with jitter.\n * If either lower or upper is null, the keys will be generated at the start or end of the list.\n */\nexport function generateNJitteredKeysBetween(\n lower: string | null,\n upper: string | null,\n n: number,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string[], Error, Random.Random> {\n return Effect.gen(function* () {\n if (n === 0) {\n return []\n }\n if (n === 1) {\n const key = yield* generateJitteredKeyBetween(lower, upper, charSet)\n return [key]\n }\n if (upper == null) {\n let newUpper = yield* generateJitteredKeyBetween(lower, upper, charSet)\n const result = [newUpper]\n for (let i = 0; i < n - 1; i++) {\n newUpper = yield* generateJitteredKeyBetween(newUpper, upper, charSet)\n result.push(newUpper)\n }\n return result\n }\n if (lower == null) {\n let newLower = yield* generateJitteredKeyBetween(lower, upper, charSet)\n const result = [newLower]\n for (let i = 0; i < n - 1; i++) {\n newLower = yield* generateJitteredKeyBetween(lower, newLower, charSet)\n result.push(newLower)\n }\n result.reverse()\n return result\n }\n const mid = Math.floor(n / 2)\n const midOrderKey = yield* generateJitteredKeyBetween(lower, upper, charSet)\n const leftKeys = yield* generateNJitteredKeysBetween(lower, midOrderKey, mid, charSet)\n const rightKeys = yield* generateNJitteredKeysBetween(midOrderKey, upper, n - mid - 1, charSet)\n return [...leftKeys, midOrderKey, ...rightKeys]\n })\n}\n\n// ============================================================================\n// Index Generator Class\n// ============================================================================\n\nexport class IndexGenerator {\n private charSet: IndexedCharacterSet\n private useJitter: boolean\n private list: string[]\n private useGroups: boolean\n private groupIdLength: number\n\n constructor(list: string[], options: GeneratorOptions = {}) {\n this.charSet = options.charSet ?? base62CharSet()\n this.useJitter = options.useJitter ?? true\n this.list = list\n this.useGroups = !!options.groupIdLength && options.groupIdLength > 0\n this.groupIdLength = options.groupIdLength ?? 0\n }\n\n /**\n * Updates the list that the generator uses to generate keys.\n * The generator will not mutate the internal list when generating keys.\n */\n public updateList(list: string[]) {\n this.list = [...list].sort()\n }\n\n /**\n * Generate any number of keys at the start of the list (before the first key).\n * Optionally you can supply a groupId to generate keys at the start of a specific group.\n */\n public nKeysStart(n: number, groupId?: string): Effect.Effect<string[], Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n yield* Effect.try(() => {\n self.validateGroupId(groupId)\n })\n const firstKey = self.firstOfGroup(groupId)\n return yield* self.generateNKeysBetween(null, firstKey, n, groupId)\n })\n }\n\n /**\n * Generate a single key at the start of the list (before the first key).\n * Optionally you can supply a groupId to generate a key at the start of a specific group.\n */\n public keyStart(groupId?: string): Effect.Effect<string, Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysStart(1, groupId)\n return keys[0]!\n })\n }\n\n /**\n * Generate any number of keys at the end of the list (after the last key).\n * Optionally you can supply a groupId to generate keys at the end of a specific group.\n */\n public nKeysEnd(n: number, groupId?: string): Effect.Effect<string[], Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n yield* Effect.try(() => {\n self.validateGroupId(groupId)\n })\n const lastKey = self.lastOfGroup(groupId)\n return yield* self.generateNKeysBetween(lastKey, null, n, groupId)\n })\n }\n\n /**\n * Generate a single key at the end of the list (after the last key).\n * Optionally you can supply a groupId to generate a key at the end of a specific group.\n */\n public keyEnd(groupId?: string): Effect.Effect<string, Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysEnd(1, groupId)\n return keys[0]!\n })\n }\n\n /**\n * Generate any number of keys behind a specific key and in front of the next key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public nKeysAfter(orderKey: string, n: number): Effect.Effect<string[], Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keyAfter = yield* self.getKeyAfter(orderKey)\n return yield* self.generateNKeysBetween(orderKey, keyAfter, n, self.groupId(orderKey))\n })\n }\n\n /**\n * Generate a single key behind a specific key and in front of the next key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public keyAfter(orderKey: string): Effect.Effect<string, Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysAfter(orderKey, 1)\n return keys[0]!\n })\n }\n\n /**\n * Generate any number of keys in front of a specific key and behind the previous key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public nKeysBefore(orderKey: string, n: number): Effect.Effect<string[], Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keyBefore = yield* self.getKeyBefore(orderKey)\n return yield* self.generateNKeysBetween(keyBefore, orderKey, n, self.groupId(orderKey))\n })\n }\n\n /**\n * Generate a single key in front of a specific key and behind the previous key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public keyBefore(orderKey: string): Effect.Effect<string, Error, Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysBefore(orderKey, 1)\n return keys[0]!\n })\n }\n\n /**\n * private function responsible for calling the correct generate function\n */\n private generateNKeysBetween(\n lowerKey: string | null,\n upperKey: string | null,\n n: number,\n groupId: string | undefined\n ): Effect.Effect<string[], Error, Random.Random> {\n const self = this\n const lower = self.groupLessKey(lowerKey)\n const upper = self.groupLessKey(upperKey)\n if (self.useJitter) {\n return Effect.gen(function* () {\n const keys = yield* generateNJitteredKeysBetween(lower, upper, n, self.charSet)\n return !groupId ? keys : keys.map((key) => groupId + key)\n })\n } else {\n // When not using jitter, we don't need Random, but TypeScript requires it\n // So we provide a default Random service that won't be used\n return Effect.gen(function* () {\n const keys = yield* generateNKeysBetween(lower, upper, n, self.charSet)\n return !groupId ? keys : keys.map((key) => groupId + key)\n }).pipe(Effect.provideService(Random as any, Random.make(Math.random())))\n }\n }\n\n /**\n * get the key before the supplied orderKey, if it exists and is in the same group\n */\n private getKeyBefore(orderKey: string): Effect.Effect<string | null, Error> {\n const index = this.list.indexOf(orderKey)\n if (index === -1) {\n return Effect.fail(new Error(`orderKey is not in the list`))\n }\n const before = this.list[index - 1]\n return Effect.succeed(!!before && this.isSameGroup(orderKey, before) ? before : null)\n }\n\n /**\n * get the key after the supplied orderKey, if it exists and is in the same group\n */\n private getKeyAfter(orderKey: string): Effect.Effect<string | null, Error> {\n const index = this.list.indexOf(orderKey)\n if (index === -1) {\n return Effect.fail(new Error(`orderKey is not in the list`))\n }\n const after = this.list[index + 1]\n return Effect.succeed(!!after && this.isSameGroup(orderKey, after) ? after : null)\n }\n\n /**\n * get the first key of the group (or the first key of the list if not using groups)\n */\n private firstOfGroup(groupId: string | undefined): string | null {\n if (!this.useGroups) return this.list[0] ?? null\n const first = this.list.find((key) => this.isPartOfGroup(key, groupId))\n return first ?? null\n }\n\n /**\n * get the last key of the group (or the last key of the list if not using groups)\n */\n private lastOfGroup(groupId: string | undefined): string | null {\n if (!this.useGroups) return this.list[this.list.length - 1] ?? null\n const allGroupItems = this.list.filter((key) =>\n this.isPartOfGroup(key, groupId)\n )\n const last = allGroupItems[allGroupItems.length - 1]\n return last ?? null\n }\n\n /**\n * throw an error if the groupId is invalid or supplied when not using groups\n */\n private validateGroupId(groupId: string | undefined): void {\n if (!this.useGroups) {\n if (groupId) {\n console.warn(\"groupId should not used when not using groups\")\n }\n return\n }\n if (!groupId) {\n throw new Error(\"groupId is required when using groups\")\n }\n if (groupId.length !== this.groupIdLength) {\n throw new Error(`groupId must be the lenght supplied in the options`)\n }\n }\n\n /**\n * get the groupId from the orderKey\n */\n private groupId(orderKey: string): string | undefined {\n if (!this.useGroups) return undefined\n return this.splitIntoGroupIdAndOrderKey(orderKey)[0]\n }\n\n /**\n * remove the groupId from the orderKey\n */\n private groupLessKey(orderKey: string | null): string | null {\n if (!this.useGroups) return orderKey\n return this.splitIntoGroupIdAndOrderKey(orderKey)[1]\n }\n\n /**\n * split the orderKey into groupId and key\n * if not using groups, orderKey will be the same as key\n */\n private splitIntoGroupIdAndOrderKey(\n orderKey: string | null\n ): [string | undefined, string | null] {\n if (!this.useGroups || !orderKey) {\n return [undefined, orderKey]\n }\n const groupId = orderKey.substring(0, this.groupIdLength)\n const key = orderKey.substring(this.groupIdLength)\n return [groupId, key]\n }\n\n /**\n * check if two keys are in the same group\n * if not using groups, keys will always be in the same group\n */\n private isSameGroup(a: string, b: string): boolean {\n if (!this.useGroups) return true\n const [aGroupId] = this.splitIntoGroupIdAndOrderKey(a)\n const [bGroupId] = this.splitIntoGroupIdAndOrderKey(b)\n return aGroupId === bGroupId\n }\n\n /**\n * check if the key is part of the group\n * if not using groups, key will always be part of the group\n */\n private isPartOfGroup(orderKey: string, groupId?: string): boolean {\n if (!this.useGroups) return true\n const [keyGroupId] = this.splitIntoGroupIdAndOrderKey(orderKey)\n return keyGroupId === groupId\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FractionalIndex.mjs","names":["byCode: Record<number, string>","byChar: Record<string, number>","paddingDict: Record<number, number>","paddingDict","_base62CharSet: IndexedCharacterSet | null","result: string[]"],"sources":["../src/FractionalIndex.ts"],"sourcesContent":["import { Effect, Random } from \"effect\"\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\nexport interface IndexCharacterSetOptions {\n chars: string // sorted string of unique characters like \"0123456789ABC\"\n jitterRange?: number // default is 1/5 of the total range created by adding 3 characters\n firstPositive?: string // default is the middle character\n mostPositive?: string // default is the last character\n mostNegative?: string // default is the first character\n}\n\nexport interface IndexedCharacterSet {\n chars: string\n byChar: Record<string, number>\n byCode: Record<number, string>\n paddingDict: Record<number, number>\n length: number\n first: string\n last: string\n firstPositive: string\n mostPositive: string\n firstNegative: string\n mostNegative: string\n jitterRange: number\n}\n\nexport type IntegerLimits = {\n firstPositive: string\n mostPositive: string\n firstNegative: string\n mostNegative: string\n}\n\nexport interface GeneratorOptions {\n charSet?: IndexedCharacterSet\n useJitter?: boolean\n groupIdLength?: number\n}\n\n// ============================================================================\n// Character Set Functions\n// ============================================================================\n\ntype CharSetDicts = {\n byCode: Record<number, string>\n byChar: Record<string, number>\n length: number\n}\n\nfunction createCharSetDicts(charSet: string): CharSetDicts {\n const byCode: Record<number, string> = {}\n const byChar: Record<string, number> = {}\n const length = charSet.length\n\n for (let i = 0; i < length; i++) {\n const char = charSet[i]\n if (char === undefined) {\n throw new Error(\"invalid charSet: missing character at index \" + i)\n }\n byCode[i] = char\n byChar[char] = i\n }\n return {\n byCode: byCode,\n byChar: byChar,\n length: length,\n }\n}\n\nfunction integerLimits(\n dicts: CharSetDicts,\n firstPositive?: string,\n mostPositive?: string,\n mostNegative?: string\n): Effect.Effect<IntegerLimits, Error> {\n return Effect.gen(function* () {\n const firstPositiveIndex = firstPositive\n ? dicts.byChar[firstPositive]\n : Math.ceil(dicts.length / 2)\n const mostPositiveIndex = mostPositive\n ? dicts.byChar[mostPositive]\n : dicts.length - 1\n const mostNegativeIndex = mostNegative ? dicts.byChar[mostNegative] : 0\n\n if (\n firstPositiveIndex === undefined ||\n mostPositiveIndex === undefined ||\n mostNegativeIndex === undefined\n ) {\n return yield* Effect.fail(new Error(\"invalid charSet\"))\n }\n if (mostPositiveIndex - firstPositiveIndex < 3) {\n return yield* Effect.fail(\n new Error(\"mostPositive must be at least 3 characters away from neutral\")\n )\n }\n if (firstPositiveIndex - mostNegativeIndex < 3) {\n return yield* Effect.fail(\n new Error(\"mostNegative must be at least 3 characters away from neutral\")\n )\n }\n\n const firstPositiveChar = dicts.byCode[firstPositiveIndex]\n const mostPositiveChar = dicts.byCode[mostPositiveIndex]\n const firstNegativeChar = dicts.byCode[firstPositiveIndex - 1]\n const mostNegativeChar = dicts.byCode[mostNegativeIndex]\n\n if (\n firstPositiveChar === undefined ||\n mostPositiveChar === undefined ||\n firstNegativeChar === undefined ||\n mostNegativeChar === undefined\n ) {\n return yield* Effect.fail(new Error(\"invalid charSet\"))\n }\n\n return {\n firstPositive: firstPositiveChar,\n mostPositive: mostPositiveChar,\n firstNegative: firstNegativeChar,\n mostNegative: mostNegativeChar,\n }\n })\n}\n\nfunction paddingDict(jitterRange: number, charSetLength: number): Record<number, number> {\n const paddingDict: Record<number, number> = {}\n for (let i = 0; i < 100; i++) {\n const value = Math.pow(charSetLength, i)\n paddingDict[i] = value\n if (value > jitterRange) {\n break\n }\n }\n return paddingDict\n}\n\nexport function validateChars(characters: string): Effect.Effect<void, Error> {\n if (characters.length < 7) {\n return Effect.fail(new Error(\"charSet must be at least 7 characters long\"))\n }\n const chars = characters.split(\"\")\n const sorted = chars.sort()\n const isEqual = sorted.join(\"\") === characters\n if (!isEqual) {\n return Effect.fail(new Error(\"charSet must be sorted\"))\n }\n return Effect.void\n}\n\nexport function indexCharacterSet(\n options: IndexCharacterSetOptions\n): Effect.Effect<IndexedCharacterSet, Error> {\n return Effect.gen(function* () {\n yield* validateChars(options.chars)\n const dicts = createCharSetDicts(options.chars)\n const limits = yield* integerLimits(\n dicts,\n options.firstPositive,\n options.mostPositive,\n options.mostNegative\n )\n // 1/5 of the total range if we add 3 characters, TODO: feels a bit arbitrary and could be improved\n const jitterRange =\n options.jitterRange ?? Math.floor(Math.pow(dicts.length, 3) / 5)\n\n const paddingRange = paddingDict(jitterRange, dicts.length)\n\n const first = dicts.byCode[0]\n const last = dicts.byCode[dicts.length - 1]\n\n if (first === undefined || last === undefined) {\n return yield* Effect.fail(new Error(\"invalid charSet\"))\n }\n\n return {\n chars: options.chars,\n byChar: dicts.byChar,\n byCode: dicts.byCode,\n length: dicts.length,\n first,\n last,\n firstPositive: limits.firstPositive,\n mostPositive: limits.mostPositive,\n firstNegative: limits.firstNegative,\n mostNegative: limits.mostNegative,\n jitterRange,\n paddingDict: paddingRange,\n }\n })\n}\n\n// cache the base62 charSet since it's the default\nlet _base62CharSet: IndexedCharacterSet | null = null\n\nexport function base62CharSet(): IndexedCharacterSet {\n if (_base62CharSet) return _base62CharSet\n // We use Effect.runSync here because base62CharSet is a synchronous API\n // and we know the parameters are valid\n _base62CharSet = Effect.runSync(\n indexCharacterSet({\n // Base62 are all the alphanumeric characters, database and user friendly\n // For shorter strings and more room you could opt for more characters\n chars: \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\",\n // This gives us nice human readable keys to start with a0 a1 etc\n firstPositive: \"a\",\n mostPositive: \"z\",\n mostNegative: \"A\",\n })\n )\n return _base62CharSet\n}\n\n// ============================================================================\n// Padding Functions\n// ============================================================================\n\nexport function makeSameLength(\n a: string,\n b: string,\n pad: \"start\" | \"end\",\n fillChar: string,\n forceLength?: number\n): [string, string] {\n const max = forceLength ?? Math.max(a.length, b.length)\n if (pad === \"start\") {\n return [a.padStart(max, fillChar), b.padStart(max, fillChar)]\n }\n return [a.padEnd(max, fillChar), b.padEnd(max, fillChar)]\n}\n\n// ============================================================================\n// Integer Length Functions\n// ============================================================================\n\nfunction distanceBetween(\n a: string,\n b: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n const indexA = charSet.byChar[a]\n const indexB = charSet.byChar[b]\n if (indexA === undefined || indexB === undefined) {\n return Effect.fail(new Error(\"invalid character in distance calculation\"))\n }\n return Effect.succeed(Math.abs(indexA - indexB))\n}\n\nfunction integerLengthFromSecondLevel(\n key: string,\n direction: \"positive\" | \"negative\",\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n if (key.length === 0) {\n return Effect.succeed(0)\n }\n const firstChar = key[0]\n if (!firstChar || firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) {\n return Effect.fail(new Error(\"invalid firstChar on key\"))\n }\n if (firstChar === charSet.mostPositive && direction === \"positive\") {\n return Effect.gen(function* () {\n const totalPositiveRoom = yield* distanceBetween(firstChar, charSet.mostNegative, charSet)\n const rest = yield* integerLengthFromSecondLevel(key.slice(1), direction, charSet)\n return totalPositiveRoom + 1 + rest\n })\n }\n if (firstChar === charSet.mostNegative && direction === \"negative\") {\n return Effect.gen(function* () {\n const totalNegativeRoom = yield* distanceBetween(firstChar, charSet.mostPositive, charSet)\n const rest = yield* integerLengthFromSecondLevel(key.slice(1), direction, charSet)\n return totalNegativeRoom + 1 + rest\n })\n }\n if (direction === \"positive\") {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.mostNegative, charSet)\n return dist + 2\n })\n } else {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.mostPositive, charSet)\n return dist + 2\n })\n }\n}\n\nexport function integerLength(\n head: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n if (head.length === 0) {\n return Effect.fail(new Error(\"head cannot be empty\"))\n }\n const firstChar = head[0]\n if (!firstChar || firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) {\n return Effect.fail(new Error(\"invalid firstChar on key\"))\n }\n if (firstChar === charSet.mostPositive) {\n return Effect.gen(function* () {\n const firstLevel = yield* distanceBetween(firstChar, charSet.firstPositive, charSet)\n const rest = yield* integerLengthFromSecondLevel(head.slice(1), \"positive\", charSet)\n return firstLevel + 1 + rest\n })\n }\n if (firstChar === charSet.mostNegative) {\n return Effect.gen(function* () {\n const firstLevel = yield* distanceBetween(firstChar, charSet.firstNegative, charSet)\n const rest = yield* integerLengthFromSecondLevel(head.slice(1), \"negative\", charSet)\n return firstLevel + 1 + rest\n })\n }\n const isPositiveRange = firstChar >= charSet.firstPositive\n if (isPositiveRange) {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.firstPositive, charSet)\n return dist + 2\n })\n } else {\n return Effect.gen(function* () {\n const dist = yield* distanceBetween(firstChar, charSet.firstNegative, charSet)\n return dist + 2\n })\n }\n}\n\n// ============================================================================\n// Key as Number Functions\n// ============================================================================\n\nexport function encodeToCharSet(int: number, charSet: IndexedCharacterSet): Effect.Effect<string, Error> {\n if (int === 0) {\n const zero = charSet.byCode[0]\n if (zero === undefined) {\n return Effect.fail(new Error(\"invalid charSet: missing code 0\"))\n }\n return Effect.succeed(zero)\n }\n let res = \"\"\n const max = charSet.length\n while (int > 0) {\n const code = charSet.byCode[int % max]\n if (code === undefined) {\n return Effect.fail(new Error(\"invalid character code in encodeToCharSet\"))\n }\n res = code + res\n int = Math.floor(int / max)\n }\n return Effect.succeed(res)\n}\n\nexport function decodeCharSetToNumber(\n key: string,\n charSet: IndexedCharacterSet\n): number {\n let res = 0\n const length = key.length\n const max = charSet.length\n for (let i = 0; i < length; i++) {\n const char = key[i]\n if (char === undefined) {\n continue\n }\n const charIndex = charSet.byChar[char]\n if (charIndex === undefined) {\n continue\n }\n res += charIndex * Math.pow(max, length - i - 1)\n }\n return res\n}\n\nexport function addCharSetKeys(\n a: string,\n b: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n const base = charSet.length\n const [paddedA, paddedB] = makeSameLength(a, b, \"start\", charSet.first)\n\n const result: string[] = []\n let carry = 0\n\n // Iterate over the digits from right to left\n for (let i = paddedA.length - 1; i >= 0; i--) {\n const charA = paddedA[i]\n const charB = paddedB[i]\n if (!charA || !charB) {\n return Effect.fail(new Error(\"invalid character in addCharSetKeys\"))\n }\n const digitA = charSet.byChar[charA]\n const digitB = charSet.byChar[charB]\n if (digitA === undefined || digitB === undefined) {\n return Effect.fail(new Error(\"invalid character in addCharSetKeys\"))\n }\n const sum = digitA + digitB + carry\n carry = Math.floor(sum / base)\n const remainder = sum % base\n\n const codeChar = charSet.byCode[remainder]\n if (codeChar === undefined) {\n return Effect.fail(new Error(\"invalid character code in addCharSetKeys\"))\n }\n result.unshift(codeChar)\n }\n\n // If there's a carry left, add it to the result\n if (carry > 0) {\n const carryChar = charSet.byCode[carry]\n if (carryChar === undefined) {\n return Effect.fail(new Error(\"invalid carry character code\"))\n }\n result.unshift(carryChar)\n }\n\n return Effect.succeed(result.join(\"\"))\n}\n\nexport function subtractCharSetKeys(\n a: string,\n b: string,\n charSet: IndexedCharacterSet,\n stripLeadingZeros = true\n): Effect.Effect<string, Error> {\n const base = charSet.length\n const [paddedA, paddedB] = makeSameLength(a, b, \"start\", charSet.first)\n\n const result: string[] = []\n let borrow = 0\n\n // Iterate over the digits from right to left\n for (let i = paddedA.length - 1; i >= 0; i--) {\n const charA = paddedA[i]\n const charB = paddedB[i]\n if (!charA || !charB) {\n return Effect.fail(new Error(\"invalid character in subtractCharSetKeys\"))\n }\n let digitA = charSet.byChar[charA]\n const digitBValue = charSet.byChar[charB]\n if (digitA === undefined || digitBValue === undefined) {\n return Effect.fail(new Error(\"invalid character in subtractCharSetKeys\"))\n }\n const digitB = digitBValue + borrow\n\n // Handle borrowing\n if (digitA < digitB) {\n borrow = 1\n digitA += base\n } else {\n borrow = 0\n }\n\n const difference = digitA - digitB\n const codeChar = charSet.byCode[difference]\n if (codeChar === undefined) {\n return Effect.fail(new Error(\"invalid character code in subtractCharSetKeys\"))\n }\n result.unshift(codeChar)\n }\n\n // If there's a borrow left, we have a negative result, which is not supported\n if (borrow > 0) {\n return Effect.fail(\n new Error(\"Subtraction result is negative. Ensure a is greater than or equal to b.\")\n )\n }\n\n // Remove leading zeros\n while (\n stripLeadingZeros &&\n result.length > 1 &&\n result[0] === charSet.first\n ) {\n result.shift()\n }\n\n return Effect.succeed(result.join(\"\"))\n}\n\nexport function incrementKey(key: string, charSet: IndexedCharacterSet): Effect.Effect<string, Error> {\n const one = charSet.byCode[1]\n if (one === undefined) {\n return Effect.fail(new Error(\"invalid charSet: missing code 1\"))\n }\n return addCharSetKeys(key, one, charSet)\n}\n\nexport function decrementKey(key: string, charSet: IndexedCharacterSet): Effect.Effect<string, Error> {\n // we should not strip leading zeros here, this will break the sorting if the key already has leading zeros\n const one = charSet.byCode[1]\n if (one === undefined) {\n return Effect.fail(new Error(\"invalid charSet: missing code 1\"))\n }\n return subtractCharSetKeys(key, one, charSet, false)\n}\n\nexport function lexicalDistance(\n a: string,\n b: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n const [lower, upper] = makeSameLength(a, b, \"end\", charSet.first).sort()\n return Effect.gen(function* () {\n const distance = yield* subtractCharSetKeys(upper, lower, charSet)\n return decodeCharSetToNumber(distance, charSet)\n })\n}\n\nexport function midPoint(\n lower: string,\n upper: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n let [paddedLower, paddedUpper] = makeSameLength(\n lower,\n upper,\n \"end\",\n charSet.first\n )\n let distance = yield* lexicalDistance(paddedLower, paddedUpper, charSet)\n if (distance === 1) {\n // if the numbers are consecutive we need more padding\n paddedLower = paddedLower.padEnd(paddedLower.length + 1, charSet.first)\n // the new distance will always be the length of the charSet\n distance = charSet.length\n }\n const mid = yield* encodeToCharSet(Math.floor(distance / 2), charSet)\n return yield* addCharSetKeys(paddedLower, mid, charSet)\n })\n}\n\n// ============================================================================\n// Integer Functions\n// ============================================================================\n\nexport function startKey(charSet: IndexedCharacterSet): string {\n return charSet.firstPositive + charSet.byCode[0]\n}\n\nexport function validInteger(integer: string, charSet: IndexedCharacterSet): Effect.Effect<boolean, Error> {\n return Effect.gen(function* () {\n const length = yield* integerLength(integer, charSet)\n return length === integer.length\n })\n}\n\nexport function validateOrderKey(\n orderKey: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<void, Error> {\n return Effect.gen(function* () {\n yield* getIntegerPart(orderKey, charSet)\n })\n}\n\nexport function getIntegerPart(\n orderKey: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const head = integerHead(orderKey, charSet)\n const integerPartLength = yield* integerLength(head, charSet)\n if (integerPartLength > orderKey.length) {\n return yield* Effect.fail(new Error(\"invalid order key length: \" + orderKey))\n }\n return orderKey.slice(0, integerPartLength)\n })\n}\n\nfunction validateInteger(integer: string, charSet: IndexedCharacterSet): Effect.Effect<void, Error> {\n return Effect.gen(function* () {\n const isValid = yield* validInteger(integer, charSet)\n if (!isValid) {\n return yield* Effect.fail(new Error(\"invalid integer length: \" + integer))\n }\n })\n}\n\nexport function integerHead(integer: string, charSet: IntegerLimits): string {\n let i = 0\n if (integer[0] === charSet.mostPositive) {\n while (integer[i] === charSet.mostPositive) {\n i = i + 1\n }\n }\n if (integer[0] === charSet.mostNegative) {\n while (integer[i] === charSet.mostNegative) {\n i = i + 1\n }\n }\n return integer.slice(0, i + 1)\n}\n\nexport function splitInteger(\n integer: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<[string, string], Error> {\n return Effect.gen(function* () {\n // We need to get the limits from the charSet\n const head = integerHead(integer, {\n firstPositive: charSet.firstPositive,\n mostPositive: charSet.mostPositive,\n firstNegative: charSet.firstNegative,\n mostNegative: charSet.mostNegative,\n })\n const tail = integer.slice(head.length)\n return [head, tail] as [string, string]\n })\n}\n\nexport function incrementIntegerHead(\n head: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const inPositiveRange = head >= charSet.firstPositive\n const nextHead = yield* incrementKey(head, charSet)\n const headIsLimitMax = head[head.length - 1] === charSet.mostPositive\n const nextHeadIsLimitMax =\n nextHead[nextHead.length - 1] === charSet.mostPositive\n\n // we can not leave the head on the limit value, we have no way to know where the head ends\n if (inPositiveRange && nextHeadIsLimitMax) {\n return nextHead + charSet.mostNegative\n }\n // we are already at the limit of this level, so we need to go up a level\n if (!inPositiveRange && headIsLimitMax) {\n return head.slice(0, head.length - 1)\n }\n return nextHead\n })\n}\n\nexport function decrementIntegerHead(\n head: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const inPositiveRange = head >= charSet.firstPositive\n const headIsLimitMin = head[head.length - 1] === charSet.mostNegative\n if (inPositiveRange && headIsLimitMin) {\n const nextLevel = head.slice(0, head.length - 1)\n // we can not leave the head on the limit value, we have no way to know where the head ends\n // so we take one extra step down\n const decremented = yield* decrementKey(nextLevel, charSet)\n return decremented\n }\n\n if (!inPositiveRange && headIsLimitMin) {\n return head + charSet.mostPositive\n }\n\n return yield* decrementKey(head, charSet)\n })\n}\n\nfunction startOnNewHead(\n head: string,\n limit: \"upper\" | \"lower\",\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n const newLength = yield* integerLength(head, charSet)\n const fillCharCode = limit === \"upper\" ? charSet.length - 1 : 0\n const fillChar = charSet.byCode[fillCharCode]\n if (fillChar === undefined) {\n return yield* Effect.fail(new Error(\"invalid fill character code\"))\n }\n return head + fillChar.repeat(newLength - head.length)\n })\n}\n\nexport function incrementInteger(\n integer: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n yield* validateInteger(integer, charSet)\n const [head, digs] = yield* splitInteger(integer, charSet)\n const maxChar = charSet.byCode[charSet.length - 1]\n if (maxChar === undefined) {\n return yield* Effect.fail(new Error(\"invalid charSet: missing max character\"))\n }\n const anyNonMaxedDigit = digs\n .split(\"\")\n .some((d) => d !== maxChar)\n\n // we have room to increment\n if (anyNonMaxedDigit) {\n const newDigits = yield* incrementKey(digs, charSet)\n return head + newDigits\n }\n const nextHead = yield* incrementIntegerHead(head, charSet)\n return yield* startOnNewHead(nextHead, \"lower\", charSet)\n })\n}\n\nexport function decrementInteger(\n integer: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n yield* validateInteger(integer, charSet)\n const [head, digs] = yield* splitInteger(integer, charSet)\n const minChar = charSet.byCode[0]\n if (minChar === undefined) {\n return yield* Effect.fail(new Error(\"invalid charSet: missing min character\"))\n }\n const anyNonLimitDigit = digs.split(\"\").some((d) => d !== minChar)\n\n // we have room to decrement\n if (anyNonLimitDigit) {\n const newDigits = yield* decrementKey(digs, charSet)\n return head + newDigits\n }\n const nextHead = yield* decrementIntegerHead(head, charSet)\n return yield* startOnNewHead(nextHead, \"upper\", charSet)\n })\n}\n\n// ============================================================================\n// Jittering Functions\n// ============================================================================\n\nexport function jitterString(\n orderKey: string,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error, typeof Random.Random> {\n return Effect.gen(function* () {\n const randomValue = yield* Random.next\n const shift = yield* encodeToCharSet(\n Math.floor(randomValue * charSet.jitterRange),\n charSet\n )\n return yield* addCharSetKeys(orderKey, shift, charSet)\n })\n}\n\nexport function padAndJitterString(\n orderKey: string,\n numberOfChars: number,\n charSet: IndexedCharacterSet\n): Effect.Effect<string, Error, typeof Random.Random> {\n return Effect.gen(function* () {\n const paddedKey = orderKey.padEnd(\n orderKey.length + numberOfChars,\n charSet.first\n )\n return yield* jitterString(paddedKey, charSet)\n })\n}\n\nexport function paddingNeededForDistance(\n distance: number,\n charSet: IndexedCharacterSet\n): number {\n const gap = charSet.jitterRange - distance\n const firstBigger = Object.entries(charSet.paddingDict).find(\n ([_key, value]) => {\n return value > gap\n }\n )\n\n return firstBigger ? parseInt(firstBigger[0]) : 0\n}\n\nexport function paddingNeededForJitter(\n orderKey: string,\n b: string | null,\n charSet: IndexedCharacterSet\n): Effect.Effect<number, Error> {\n return Effect.gen(function* () {\n const integer = yield* getIntegerPart(orderKey, charSet)\n const nextInteger = yield* incrementInteger(integer, charSet)\n let needed = 0\n if (b !== null) {\n const distanceToB = yield* lexicalDistance(orderKey, b, charSet)\n if (distanceToB < charSet.jitterRange + 1) {\n needed = Math.max(needed, paddingNeededForDistance(distanceToB, charSet))\n }\n }\n const distanceToNextInteger = yield* lexicalDistance(orderKey, nextInteger, charSet)\n if (distanceToNextInteger < charSet.jitterRange + 1) {\n needed = Math.max(\n needed,\n paddingNeededForDistance(distanceToNextInteger, charSet)\n )\n }\n\n return needed\n })\n}\n\n// ============================================================================\n// Key Generation Functions\n// ============================================================================\n\n/**\n * Generate a key between two other keys.\n * If either lower or upper is null, the key will be generated at the start or end of the list.\n */\nexport function generateKeyBetween(\n lower: string | null,\n upper: string | null,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string, Error> {\n return Effect.gen(function* () {\n if (lower !== null) {\n yield* validateOrderKey(lower, charSet)\n }\n if (upper !== null) {\n yield* validateOrderKey(upper, charSet)\n }\n if (lower === null && upper === null) {\n return startKey(charSet)\n }\n if (lower === null) {\n const integer = yield* getIntegerPart(upper!, charSet)\n return yield* decrementInteger(integer, charSet)\n }\n if (upper === null) {\n const integer = yield* getIntegerPart(lower, charSet)\n return yield* incrementInteger(integer, charSet)\n }\n if (lower >= upper) {\n return yield* Effect.fail(new Error(lower + \" >= \" + upper))\n }\n return yield* midPoint(lower, upper, charSet)\n })\n}\n\ntype GenerateKeyBetweenFunc = (\n lower: string | null,\n upper: string | null,\n charSet?: IndexedCharacterSet\n) => Effect.Effect<string, Error>\n\ntype GenerateNKeysBetweenFunc = (\n lower: string | null,\n upper: string | null,\n n: number,\n charSet?: IndexedCharacterSet\n) => Effect.Effect<string[], Error>\n\nfunction spreadGeneratorResults(\n lower: string | null,\n upper: string | null,\n n: number,\n charSet: IndexedCharacterSet,\n generateKey: GenerateKeyBetweenFunc,\n generateNKeys: GenerateNKeysBetweenFunc\n): Effect.Effect<string[], Error> {\n if (n === 0) {\n return Effect.succeed([])\n }\n if (n === 1) {\n return generateKey(lower, upper, charSet).pipe(Effect.map((key) => [key]))\n }\n if (upper == null) {\n return Effect.gen(function* () {\n let newUpper = yield* generateKey(lower, upper, charSet)\n const result = [newUpper]\n for (let i = 0; i < n - 1; i++) {\n newUpper = yield* generateKey(newUpper, upper, charSet)\n result.push(newUpper)\n }\n return result\n })\n }\n if (lower == null) {\n return Effect.gen(function* () {\n let newLower = yield* generateKey(lower, upper, charSet)\n const result = [newLower]\n for (let i = 0; i < n - 1; i++) {\n newLower = yield* generateKey(lower, newLower, charSet)\n result.push(newLower)\n }\n result.reverse()\n return result\n })\n }\n return Effect.gen(function* () {\n const mid = Math.floor(n / 2)\n const midOrderKey = yield* generateKey(lower, upper, charSet)\n const leftKeys = yield* generateNKeys(lower, midOrderKey, mid, charSet)\n const rightKeys = yield* generateNKeys(midOrderKey, upper, n - mid - 1, charSet)\n return [...leftKeys, midOrderKey, ...rightKeys]\n })\n}\n\n/**\n * Generate any number of keys between two other keys.\n * If either lower or upper is null, the keys will be generated at the start or end of the list.\n */\nexport function generateNKeysBetween(\n a: string | null,\n b: string | null,\n n: number,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string[], Error> {\n return spreadGeneratorResults(\n a,\n b,\n n,\n charSet,\n (lower, upper, charSet = base62CharSet()) => generateKeyBetween(lower, upper, charSet),\n (lower, upper, n, charSet = base62CharSet()) => generateNKeysBetween(lower, upper, n, charSet)\n )\n}\n\n/**\n * Generate a key between two other keys with jitter.\n * If either lower or upper is null, the key will be generated at the start or end of the list.\n */\nexport function generateJitteredKeyBetween(\n lower: string | null,\n upper: string | null,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string, Error, typeof Random.Random> {\n return Effect.gen(function* () {\n const key = yield* generateKeyBetween(lower, upper, charSet)\n const paddingNeeded = yield* paddingNeededForJitter(key, upper, charSet)\n if (paddingNeeded) {\n return yield* padAndJitterString(key, paddingNeeded, charSet)\n }\n return yield* jitterString(key, charSet)\n })\n}\n\n/**\n * Generate any number of keys between two other keys with jitter.\n * If either lower or upper is null, the keys will be generated at the start or end of the list.\n */\nexport function generateNJitteredKeysBetween(\n lower: string | null,\n upper: string | null,\n n: number,\n charSet: IndexedCharacterSet = base62CharSet()\n): Effect.Effect<string[], Error, typeof Random.Random> {\n return Effect.gen(function* () {\n if (n === 0) {\n return []\n }\n if (n === 1) {\n const key = yield* generateJitteredKeyBetween(lower, upper, charSet)\n return [key]\n }\n if (upper == null) {\n let newUpper = yield* generateJitteredKeyBetween(lower, upper, charSet)\n const result = [newUpper]\n for (let i = 0; i < n - 1; i++) {\n newUpper = yield* generateJitteredKeyBetween(newUpper, upper, charSet)\n result.push(newUpper)\n }\n return result\n }\n if (lower == null) {\n let newLower = yield* generateJitteredKeyBetween(lower, upper, charSet)\n const result = [newLower]\n for (let i = 0; i < n - 1; i++) {\n newLower = yield* generateJitteredKeyBetween(lower, newLower, charSet)\n result.push(newLower)\n }\n result.reverse()\n return result\n }\n const mid = Math.floor(n / 2)\n const midOrderKey = yield* generateJitteredKeyBetween(lower, upper, charSet)\n const leftKeys = yield* generateNJitteredKeysBetween(lower, midOrderKey, mid, charSet)\n const rightKeys = yield* generateNJitteredKeysBetween(midOrderKey, upper, n - mid - 1, charSet)\n return [...leftKeys, midOrderKey, ...rightKeys]\n })\n}\n\n// ============================================================================\n// Index Generator Class\n// ============================================================================\n\nexport class IndexGenerator {\n private charSet: IndexedCharacterSet\n private useJitter: boolean\n private list: string[]\n private useGroups: boolean\n private groupIdLength: number\n\n constructor(list: string[], options: GeneratorOptions = {}) {\n this.charSet = options.charSet ?? base62CharSet()\n this.useJitter = options.useJitter ?? true\n this.list = list\n this.useGroups = !!options.groupIdLength && options.groupIdLength > 0\n this.groupIdLength = options.groupIdLength ?? 0\n }\n\n /**\n * Updates the list that the generator uses to generate keys.\n * The generator will not mutate the internal list when generating keys.\n */\n public updateList(list: string[]) {\n this.list = [...list].sort()\n }\n\n /**\n * Generate any number of keys at the start of the list (before the first key).\n * Optionally you can supply a groupId to generate keys at the start of a specific group.\n */\n public nKeysStart(n: number, groupId?: string): Effect.Effect<string[], Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n yield* Effect.try({ try: () => {\n self.validateGroupId(groupId)\n }, catch: (e) => e instanceof Error ? e : new Error(String(e)) })\n const firstKey = self.firstOfGroup(groupId)\n return yield* self.generateNKeysBetween(null, firstKey, n, groupId)\n })\n }\n\n /**\n * Generate a single key at the start of the list (before the first key).\n * Optionally you can supply a groupId to generate a key at the start of a specific group.\n */\n public keyStart(groupId?: string): Effect.Effect<string, Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysStart(1, groupId)\n return keys[0]!\n })\n }\n\n /**\n * Generate any number of keys at the end of the list (after the last key).\n * Optionally you can supply a groupId to generate keys at the end of a specific group.\n */\n public nKeysEnd(n: number, groupId?: string): Effect.Effect<string[], Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n yield* Effect.try({ try: () => {\n self.validateGroupId(groupId)\n }, catch: (e) => e instanceof Error ? e : new Error(String(e)) })\n const lastKey = self.lastOfGroup(groupId)\n return yield* self.generateNKeysBetween(lastKey, null, n, groupId)\n })\n }\n\n /**\n * Generate a single key at the end of the list (after the last key).\n * Optionally you can supply a groupId to generate a key at the end of a specific group.\n */\n public keyEnd(groupId?: string): Effect.Effect<string, Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysEnd(1, groupId)\n return keys[0]!\n })\n }\n\n /**\n * Generate any number of keys behind a specific key and in front of the next key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public nKeysAfter(orderKey: string, n: number): Effect.Effect<string[], Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keyAfter = yield* self.getKeyAfter(orderKey)\n return yield* self.generateNKeysBetween(orderKey, keyAfter, n, self.groupId(orderKey))\n })\n }\n\n /**\n * Generate a single key behind a specific key and in front of the next key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public keyAfter(orderKey: string): Effect.Effect<string, Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysAfter(orderKey, 1)\n return keys[0]!\n })\n }\n\n /**\n * Generate any number of keys in front of a specific key and behind the previous key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public nKeysBefore(orderKey: string, n: number): Effect.Effect<string[], Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keyBefore = yield* self.getKeyBefore(orderKey)\n return yield* self.generateNKeysBetween(keyBefore, orderKey, n, self.groupId(orderKey))\n })\n }\n\n /**\n * Generate a single key in front of a specific key and behind the previous key.\n * GroupId will be inferred from the orderKey if working with groups\n */\n public keyBefore(orderKey: string): Effect.Effect<string, Error, typeof Random.Random> {\n const self = this\n return Effect.gen(function* () {\n const keys = yield* self.nKeysBefore(orderKey, 1)\n return keys[0]!\n })\n }\n\n /**\n * private function responsible for calling the correct generate function\n */\n private generateNKeysBetween(\n lowerKey: string | null,\n upperKey: string | null,\n n: number,\n groupId: string | undefined\n ): Effect.Effect<string[], Error, typeof Random.Random> {\n const self = this\n const lower = self.groupLessKey(lowerKey)\n const upper = self.groupLessKey(upperKey)\n if (self.useJitter) {\n return Effect.gen(function* () {\n const keys = yield* generateNJitteredKeysBetween(lower, upper, n, self.charSet)\n return !groupId ? keys : keys.map((key) => groupId + key)\n })\n } else {\n // When not using jitter, we don't need Random, but TypeScript requires it\n // So we provide a default Random service that won't be used\n return Effect.gen(function* () {\n const keys = yield* generateNKeysBetween(lower, upper, n, self.charSet)\n return !groupId ? keys : keys.map((key) => groupId + key)\n }).pipe(Random.withSeed(Math.random()))\n }\n }\n\n /**\n * get the key before the supplied orderKey, if it exists and is in the same group\n */\n private getKeyBefore(orderKey: string): Effect.Effect<string | null, Error> {\n const index = this.list.indexOf(orderKey)\n if (index === -1) {\n return Effect.fail(new Error(`orderKey is not in the list`))\n }\n const before = this.list[index - 1]\n return Effect.succeed(!!before && this.isSameGroup(orderKey, before) ? before : null)\n }\n\n /**\n * get the key after the supplied orderKey, if it exists and is in the same group\n */\n private getKeyAfter(orderKey: string): Effect.Effect<string | null, Error> {\n const index = this.list.indexOf(orderKey)\n if (index === -1) {\n return Effect.fail(new Error(`orderKey is not in the list`))\n }\n const after = this.list[index + 1]\n return Effect.succeed(!!after && this.isSameGroup(orderKey, after) ? after : null)\n }\n\n /**\n * get the first key of the group (or the first key of the list if not using groups)\n */\n private firstOfGroup(groupId: string | undefined): string | null {\n if (!this.useGroups) return this.list[0] ?? null\n const first = this.list.find((key) => this.isPartOfGroup(key, groupId))\n return first ?? null\n }\n\n /**\n * get the last key of the group (or the last key of the list if not using groups)\n */\n private lastOfGroup(groupId: string | undefined): string | null {\n if (!this.useGroups) return this.list[this.list.length - 1] ?? null\n const allGroupItems = this.list.filter((key) =>\n this.isPartOfGroup(key, groupId)\n )\n const last = allGroupItems[allGroupItems.length - 1]\n return last ?? null\n }\n\n /**\n * throw an error if the groupId is invalid or supplied when not using groups\n */\n private validateGroupId(groupId: string | undefined): void {\n if (!this.useGroups) {\n if (groupId) {\n console.warn(\"groupId should not used when not using groups\")\n }\n return\n }\n if (!groupId) {\n throw new Error(\"groupId is required when using groups\")\n }\n if (groupId.length !== this.groupIdLength) {\n throw new Error(`groupId must be the lenght supplied in the options`)\n }\n }\n\n /**\n * get the groupId from the orderKey\n */\n private groupId(orderKey: string): string | undefined {\n if (!this.useGroups) return undefined\n return this.splitIntoGroupIdAndOrderKey(orderKey)[0]\n }\n\n /**\n * remove the groupId from the orderKey\n */\n private groupLessKey(orderKey: string | null): string | null {\n if (!this.useGroups) return orderKey\n return this.splitIntoGroupIdAndOrderKey(orderKey)[1]\n }\n\n /**\n * split the orderKey into groupId and key\n * if not using groups, orderKey will be the same as key\n */\n private splitIntoGroupIdAndOrderKey(\n orderKey: string | null\n ): [string | undefined, string | null] {\n if (!this.useGroups || !orderKey) {\n return [undefined, orderKey]\n }\n const groupId = orderKey.substring(0, this.groupIdLength)\n const key = orderKey.substring(this.groupIdLength)\n return [groupId, key]\n }\n\n /**\n * check if two keys are in the same group\n * if not using groups, keys will always be in the same group\n */\n private isSameGroup(a: string, b: string): boolean {\n if (!this.useGroups) return true\n const [aGroupId] = this.splitIntoGroupIdAndOrderKey(a)\n const [bGroupId] = this.splitIntoGroupIdAndOrderKey(b)\n return aGroupId === bGroupId\n }\n\n /**\n * check if the key is part of the group\n * if not using groups, key will always be part of the group\n */\n private isPartOfGroup(orderKey: string, groupId?: string): boolean {\n if (!this.useGroups) return true\n const [keyGroupId] = this.splitIntoGroupIdAndOrderKey(orderKey)\n return keyGroupId === groupId\n }\n}\n"],"mappings":"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"}
@@ -6,13 +6,13 @@ import { Schema } from "effect";
6
6
  declare namespace Operation_d_exports {
7
7
  export { EncodedOperation, Operation, decode, encode, fromDefinition };
8
8
  }
9
- type Operation<TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition<TKind, TPayload, any>> = {
9
+ type Operation<TKind, TPayload extends Schema.Top, TDef extends OperationDefinition<TKind, TPayload, any>> = {
10
10
  readonly kind: TKind;
11
11
  readonly path: OperationPath;
12
12
  readonly payload: Schema.Schema.Type<TPayload>;
13
13
  readonly deduplicable?: boolean;
14
14
  } & TDef;
15
- declare const fromDefinition: <TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition<TKind, TPayload, any>>(operationPath: OperationPath, definition: TDef, payload: Schema.Schema.Type<TPayload>) => Operation<TKind, TPayload, TDef>;
15
+ declare const fromDefinition: <TKind, TPayload extends Schema.Top, TDef extends OperationDefinition<TKind, TPayload, any>>(operationPath: OperationPath, definition: TDef, payload: Schema.Schema.Type<TPayload>) => Operation<TKind, TPayload, TDef>;
16
16
  /**
17
17
  * Encoded representation of an Operation for network transport.
18
18
  */
@@ -26,7 +26,7 @@ interface EncodedOperation {
26
26
  * @param operation - The operation to encode.
27
27
  * @returns The encoded representation.
28
28
  */
29
- declare const encode: <TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition<TKind, TPayload, any>>(operation: Operation<TKind, TPayload, TDef>) => EncodedOperation;
29
+ declare const encode: <TKind, TPayload extends Schema.Top, TDef extends OperationDefinition<TKind, TPayload, any>>(operation: Operation<TKind, TPayload, TDef>) => EncodedOperation;
30
30
  /**
31
31
  * Decodes an encoded operation back to an Operation.
32
32
  * Note: This returns a partial operation without the definition methods.
@@ -34,7 +34,7 @@ declare const encode: <TKind, TPayload extends Schema.Schema.Any, TDef extends O
34
34
  * @param encoded - The encoded representation.
35
35
  * @returns The decoded Operation (without definition-specific methods).
36
36
  */
37
- declare const decode: (encoded: EncodedOperation) => Operation<unknown, Schema.Schema.Any, any>;
37
+ declare const decode: (encoded: EncodedOperation) => Operation<unknown, Schema.Top, any>;
38
38
  //#endregion
39
39
  export { EncodedOperation, Operation, Operation_d_exports };
40
40
  //# sourceMappingURL=Operation.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Operation.d.cts","names":[],"sources":["../src/Operation.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAMY,kCAAkC,MAAA,CAAO,MAAA,CAAO,kBAAkB,oBAAwC,OAAO;iBAC1G;iBACA;oBACG,MAAA,CAAO,MAAA,CAAO,KAAK;;IAGrC;cAES,yCAA0C,MAAA,CAAO,MAAA,CAAO,kBAAkB,oBAAwC,OAAO,+BAA+B,2BAAyC,eAAe,MAAA,CAAO,MAAA,CAAO,KAAK,cAAY,UAAU,OAAO,UAAU;;;;AAR3Q,UAoBK,gBAAA,CApBI;EAAyB,SAAO,IAAO,EAAA,OAAA;EAA0D,SAAA,IAAA,EAsBnG,oBAtBmG;EAAO,SAAA,OAAA,EAAA,OAAA;;;;;;;AAMrH,cAyBK,MAzBL,EAAA,CAAA,KAAA,EAAA,iBAyBuC,MAAA,CAAO,MAAA,CAAO,GAzBrD,EAAA,aAyBuE,mBAzBvE,CAyB+G,KAzB/G,EAyBsH,QAzBtH,EAAA,GAAA,CAAA,CAAA,CAAA,SAAA,EA0BO,SA1BP,CA0BiB,KA1BjB,EA0BwB,QA1BxB,EA0BkC,IA1BlC,CAAA,EAAA,GA2BL,gBA3BK;AAER;;;;;;;AAAgP,cAwCnO,MAxCmO,EAAA,CAAA,OAAA,EAwChN,gBAxCgN,EAAA,GAwC7L,SAxC6L,CAAA,OAAA,EAwC1K,MAAA,CAAO,MAAA,CAAO,GAxC4J,EAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"Operation.d.cts","names":[],"sources":["../src/Operation.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAMY,kCAAkC,MAAA,CAAO,kBAAkB,oBAAwC,OAAO;iBACnG;iBACA;oBACG,MAAA,CAAO,MAAA,CAAO,KAAK;;IAGrC;cAES,yCAA0C,MAAA,CAAO,kBAAkB,oBAAwC,OAAO,+BAA+B,2BAAyC,eAAe,MAAA,CAAO,MAAA,CAAO,KAAK,cAAY,UAAU,OAAO,UAAU;;;;AARpQ,UAoBK,gBAAA,CApBI;EAAyB,SAAO,IAAA,EAAA,OAAA;EAA0D,SAAA,IAAA,EAsB5F,oBAtB4F;EAAO,SAAA,OAAA,EAAA,OAAA;;;;;;;AAM9G,cAyBK,MAzBL,EAAA,CAAA,KAAA,EAAA,iBAyBuC,MAAA,CAAO,GAzB9C,EAAA,aAyBgE,mBAzBhE,CAyBwG,KAzBxG,EAyB+G,QAzB/G,EAAA,GAAA,CAAA,CAAA,CAAA,SAAA,EA0BO,SA1BP,CA0BiB,KA1BjB,EA0BwB,QA1BxB,EA0BkC,IA1BlC,CAAA,EAAA,GA2BL,gBA3BK;AAER;;;;;;;AAAyO,cAwC5N,MAxC4N,EAAA,CAAA,OAAA,EAwCzM,gBAxCyM,EAAA,GAwCtL,SAxCsL,CAAA,OAAA,EAwCnK,MAAA,CAAO,GAxC4J,EAAA,GAAA,CAAA"}
@@ -6,13 +6,13 @@ import { Schema } from "effect";
6
6
  declare namespace Operation_d_exports {
7
7
  export { EncodedOperation, Operation, decode, encode, fromDefinition };
8
8
  }
9
- type Operation<TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition<TKind, TPayload, any>> = {
9
+ type Operation<TKind, TPayload extends Schema.Top, TDef extends OperationDefinition<TKind, TPayload, any>> = {
10
10
  readonly kind: TKind;
11
11
  readonly path: OperationPath;
12
12
  readonly payload: Schema.Schema.Type<TPayload>;
13
13
  readonly deduplicable?: boolean;
14
14
  } & TDef;
15
- declare const fromDefinition: <TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition<TKind, TPayload, any>>(operationPath: OperationPath, definition: TDef, payload: Schema.Schema.Type<TPayload>) => Operation<TKind, TPayload, TDef>;
15
+ declare const fromDefinition: <TKind, TPayload extends Schema.Top, TDef extends OperationDefinition<TKind, TPayload, any>>(operationPath: OperationPath, definition: TDef, payload: Schema.Schema.Type<TPayload>) => Operation<TKind, TPayload, TDef>;
16
16
  /**
17
17
  * Encoded representation of an Operation for network transport.
18
18
  */
@@ -26,7 +26,7 @@ interface EncodedOperation {
26
26
  * @param operation - The operation to encode.
27
27
  * @returns The encoded representation.
28
28
  */
29
- declare const encode: <TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition<TKind, TPayload, any>>(operation: Operation<TKind, TPayload, TDef>) => EncodedOperation;
29
+ declare const encode: <TKind, TPayload extends Schema.Top, TDef extends OperationDefinition<TKind, TPayload, any>>(operation: Operation<TKind, TPayload, TDef>) => EncodedOperation;
30
30
  /**
31
31
  * Decodes an encoded operation back to an Operation.
32
32
  * Note: This returns a partial operation without the definition methods.
@@ -34,7 +34,7 @@ declare const encode: <TKind, TPayload extends Schema.Schema.Any, TDef extends O
34
34
  * @param encoded - The encoded representation.
35
35
  * @returns The decoded Operation (without definition-specific methods).
36
36
  */
37
- declare const decode: (encoded: EncodedOperation) => Operation<unknown, Schema.Schema.Any, any>;
37
+ declare const decode: (encoded: EncodedOperation) => Operation<unknown, Schema.Top, any>;
38
38
  //#endregion
39
39
  export { EncodedOperation, Operation, Operation_d_exports };
40
40
  //# sourceMappingURL=Operation.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Operation.d.mts","names":[],"sources":["../src/Operation.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAMY,kCAAkC,MAAA,CAAO,MAAA,CAAO,kBAAkB,oBAAwC,OAAO;iBAC1G;iBACA;oBACG,MAAA,CAAO,MAAA,CAAO,KAAK;;IAGrC;cAES,yCAA0C,MAAA,CAAO,MAAA,CAAO,kBAAkB,oBAAwC,OAAO,+BAA+B,2BAAyC,eAAe,MAAA,CAAO,MAAA,CAAO,KAAK,cAAY,UAAU,OAAO,UAAU;;;;AAR3Q,UAoBK,gBAAA,CApBI;EAAyB,SAAO,IAAO,EAAA,OAAA;EAA0D,SAAA,IAAA,EAsBnG,oBAtBmG;EAAO,SAAA,OAAA,EAAA,OAAA;;;;;;;AAMrH,cAyBK,MAzBL,EAAA,CAAA,KAAA,EAAA,iBAyBuC,MAAA,CAAO,MAAA,CAAO,GAzBrD,EAAA,aAyBuE,mBAzBvE,CAyB+G,KAzB/G,EAyBsH,QAzBtH,EAAA,GAAA,CAAA,CAAA,CAAA,SAAA,EA0BO,SA1BP,CA0BiB,KA1BjB,EA0BwB,QA1BxB,EA0BkC,IA1BlC,CAAA,EAAA,GA2BL,gBA3BK;AAER;;;;;;;AAAgP,cAwCnO,MAxCmO,EAAA,CAAA,OAAA,EAwChN,gBAxCgN,EAAA,GAwC7L,SAxC6L,CAAA,OAAA,EAwC1K,MAAA,CAAO,MAAA,CAAO,GAxC4J,EAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"Operation.d.mts","names":[],"sources":["../src/Operation.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAMY,kCAAkC,MAAA,CAAO,kBAAkB,oBAAwC,OAAO;iBACnG;iBACA;oBACG,MAAA,CAAO,MAAA,CAAO,KAAK;;IAGrC;cAES,yCAA0C,MAAA,CAAO,kBAAkB,oBAAwC,OAAO,+BAA+B,2BAAyC,eAAe,MAAA,CAAO,MAAA,CAAO,KAAK,cAAY,UAAU,OAAO,UAAU;;;;AARpQ,UAoBK,gBAAA,CApBI;EAAyB,SAAO,IAAA,EAAA,OAAA;EAA0D,SAAA,IAAA,EAsB5F,oBAtB4F;EAAO,SAAA,OAAA,EAAA,OAAA;;;;;;;AAM9G,cAyBK,MAzBL,EAAA,CAAA,KAAA,EAAA,iBAyBuC,MAAA,CAAO,GAzB9C,EAAA,aAyBgE,mBAzBhE,CAyBwG,KAzBxG,EAyB+G,QAzB/G,EAAA,GAAA,CAAA,CAAA,CAAA,SAAA,EA0BO,SA1BP,CA0BiB,KA1BjB,EA0BwB,QA1BxB,EA0BkC,IA1BlC,CAAA,EAAA,GA2BL,gBA3BK;AAER;;;;;;;AAAyO,cAwC5N,MAxC4N,EAAA,CAAA,OAAA,EAwCzM,gBAxCyM,EAAA,GAwCtL,SAxCsL,CAAA,OAAA,EAwCnK,MAAA,CAAO,GAxC4J,EAAA,GAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Operation.mjs","names":["OperationPath.encode","OperationPath.decode"],"sources":["../src/Operation.ts"],"sourcesContent":["\nimport * as OperationPath from \"./OperationPath\"\nimport * as OperationDefinition from \"./OperationDefinition\"\nimport { Schema } from \"effect\";\n\n\nexport type Operation<TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition.OperationDefinition<TKind, TPayload, any>> = {\n readonly kind: TKind\n readonly path: OperationPath.OperationPath\n readonly payload: Schema.Schema.Type<TPayload>,\n readonly deduplicable?: boolean\n\n} & TDef\n\nexport const fromDefinition = <TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition.OperationDefinition<TKind, TPayload, any>>(operationPath: OperationPath.OperationPath, definition: TDef, payload: Schema.Schema.Type<TPayload>): Operation<TKind, TPayload, TDef> => {\n return {\n kind: definition.kind,\n path: operationPath,\n payload: payload,\n ...(definition.deduplicable !== undefined ? { deduplicable: definition.deduplicable } : {}),\n } as Operation<TKind, TPayload, TDef>\n}\n\n/**\n * Encoded representation of an Operation for network transport.\n */\nexport interface EncodedOperation {\n readonly kind: unknown\n readonly path: OperationPath.EncodedOperationPath\n readonly payload: unknown\n}\n\n/**\n * Encodes an Operation to a JSON-serializable format for network transport.\n * @param operation - The operation to encode.\n * @returns The encoded representation.\n */\nexport const encode = <TKind, TPayload extends Schema.Schema.Any, TDef extends OperationDefinition.OperationDefinition<TKind, TPayload, any>>(\n operation: Operation<TKind, TPayload, TDef>\n): EncodedOperation => {\n return {\n kind: operation.kind,\n path: OperationPath.encode(operation.path),\n payload: operation.payload,\n }\n}\n\n/**\n * Decodes an encoded operation back to an Operation.\n * Note: This returns a partial operation without the definition methods.\n * The caller must have the operation definitions to fully reconstruct if needed.\n * @param encoded - The encoded representation.\n * @returns The decoded Operation (without definition-specific methods).\n */\nexport const decode = (encoded: EncodedOperation): Operation<unknown, Schema.Schema.Any, any> => {\n return {\n kind: encoded.kind,\n path: OperationPath.decode(encoded.path),\n payload: encoded.payload,\n } as Operation<unknown, Schema.Schema.Any, any>\n}"],"mappings":";;;;;;;;;;AAcA,MAAa,kBAAyI,eAA4C,YAAkB,YAA4E;AAC5R;EACI,MAAM,WAAW;EACjB,MAAM;EACG;IACL,WAAW,iBAAiB,SAAY,EAAE,cAAc,WAAW,cAAc,GAAG,EAAE;;;;;;;AAkBlG,MAAa,UACT,cACmB;AACnB,QAAO;EACH,MAAM,UAAU;EAChB,MAAMA,SAAqB,UAAU,KAAK;EAC1C,SAAS,UAAU;EACtB;;;;;;;;;AAUL,MAAa,UAAU,YAA0E;AAC7F,QAAO;EACH,MAAM,QAAQ;EACd,MAAMC,SAAqB,QAAQ,KAAK;EACxC,SAAS,QAAQ;EACpB"}
1
+ {"version":3,"file":"Operation.mjs","names":["OperationPath.encode","OperationPath.decode"],"sources":["../src/Operation.ts"],"sourcesContent":["\nimport * as OperationPath from \"./OperationPath\"\nimport * as OperationDefinition from \"./OperationDefinition\"\nimport { Schema } from \"effect\";\n\n\nexport type Operation<TKind, TPayload extends Schema.Top, TDef extends OperationDefinition.OperationDefinition<TKind, TPayload, any>> = {\n readonly kind: TKind\n readonly path: OperationPath.OperationPath\n readonly payload: Schema.Schema.Type<TPayload>,\n readonly deduplicable?: boolean\n\n} & TDef\n\nexport const fromDefinition = <TKind, TPayload extends Schema.Top, TDef extends OperationDefinition.OperationDefinition<TKind, TPayload, any>>(operationPath: OperationPath.OperationPath, definition: TDef, payload: Schema.Schema.Type<TPayload>): Operation<TKind, TPayload, TDef> => {\n return {\n kind: definition.kind,\n path: operationPath,\n payload: payload,\n ...(definition.deduplicable !== undefined ? { deduplicable: definition.deduplicable } : {}),\n } as Operation<TKind, TPayload, TDef>\n}\n\n/**\n * Encoded representation of an Operation for network transport.\n */\nexport interface EncodedOperation {\n readonly kind: unknown\n readonly path: OperationPath.EncodedOperationPath\n readonly payload: unknown\n}\n\n/**\n * Encodes an Operation to a JSON-serializable format for network transport.\n * @param operation - The operation to encode.\n * @returns The encoded representation.\n */\nexport const encode = <TKind, TPayload extends Schema.Top, TDef extends OperationDefinition.OperationDefinition<TKind, TPayload, any>>(\n operation: Operation<TKind, TPayload, TDef>\n): EncodedOperation => {\n return {\n kind: operation.kind,\n path: OperationPath.encode(operation.path),\n payload: operation.payload,\n }\n}\n\n/**\n * Decodes an encoded operation back to an Operation.\n * Note: This returns a partial operation without the definition methods.\n * The caller must have the operation definitions to fully reconstruct if needed.\n * @param encoded - The encoded representation.\n * @returns The decoded Operation (without definition-specific methods).\n */\nexport const decode = (encoded: EncodedOperation): Operation<unknown, Schema.Top, any> => {\n return {\n kind: encoded.kind,\n path: OperationPath.decode(encoded.path),\n payload: encoded.payload,\n } as Operation<unknown, Schema.Top, any>\n}"],"mappings":";;;;;;;;;;AAcA,MAAa,kBAAkI,eAA4C,YAAkB,YAA4E;AACrR;EACI,MAAM,WAAW;EACjB,MAAM;EACG;IACL,WAAW,iBAAiB,SAAY,EAAE,cAAc,WAAW,cAAc,GAAG,EAAE;;;;;;;AAkBlG,MAAa,UACT,cACmB;AACnB,QAAO;EACH,MAAM,UAAU;EAChB,MAAMA,SAAqB,UAAU,KAAK;EAC1C,SAAS,UAAU;EACtB;;;;;;;;;AAUL,MAAa,UAAU,YAAmE;AACtF,QAAO;EACH,MAAM,QAAQ;EACd,MAAMC,SAAqB,QAAQ,KAAK;EACxC,SAAS,QAAQ;EACpB"}
@@ -5,13 +5,13 @@ declare namespace OperationDefinition_d_exports {
5
5
  export { OperationDefinition, make };
6
6
  }
7
7
  type Mutable<T> = T extends ReadonlyArray<infer U> ? Array<U> : { -readonly [K in keyof T]: T[K] };
8
- interface OperationDefinition<TKind, TPayload extends Schema.Schema.Any, TTarget extends Schema.Schema.Any> {
8
+ interface OperationDefinition<TKind, TPayload extends Schema.Top, TTarget extends Schema.Top> {
9
9
  readonly kind: TKind;
10
10
  readonly payload: TPayload;
11
11
  readonly target: TTarget;
12
12
  readonly deduplicable?: boolean;
13
13
  }
14
- declare const make: <TKind, TPayload extends Schema.Schema.Any, TTarget extends Schema.Schema.Any>(options: {
14
+ declare const make: <TKind, TPayload extends Schema.Top, TTarget extends Schema.Top>(options: {
15
15
  readonly kind: TKind;
16
16
  readonly payload: TPayload;
17
17
  readonly target: TTarget;
@@ -1 +1 @@
1
- {"version":3,"file":"OperationDefinition.d.cts","names":[],"sources":["../src/OperationDefinition.ts"],"sourcesContent":[],"mappings":";;;;;;KAEK,aAAa,UAAU,yBAAyB,MAAM,6BAA6B,IAAI,EAAE;UAE7E,4CAA4C,MAAA,CAAO,MAAA,CAAO,qBAAqB,MAAA,CAAO,MAAA,CAAO;iBAC3F;oBACG;mBACD;EALhB,SAAA,YAAO,CAAA,EAAA,OAAA;;AAAgB,cASf,IATe,EAAA,CAAA,KAAA,EAAA,iBASiB,MAAA,CAAO,MAAA,CAAO,GAT/B,EAAA,gBASoD,MAAA,CAAO,MAAA,CAAO,GATlE,CAAA,CAAA,OAAA,EAAA;EAA+B,SAAA,IAAA,EAUxC,KAVwC;EAAN,SAAA,OAAA,EAW/B,QAX+B;EAAmC,SAAA,MAAA,EAYnE,OAZmE;EAAI,SAAA,KAAA,EAAA,CAAA,OAAA,EAa9D,MAAA,CAAO,MAAA,CAAO,IAbgD,CAa3C,QAb2C,CAAA,EAAA,MAAA,EAaxB,OAbwB,CAahB,MAAA,CAAO,MAAA,CAAO,IAbE,CAaG,OAbH,CAAA,CAAA,EAAA,GAAA,IAAA;EAAE,SAAA,YAAA,CAAA,EAAA,OAAA;CAAC,EAAA,GAAA;EAE9E,SAAA,YAAA,CAAmB,EAAA,OAAA,GAAA,SAAA;EAAyB,SAAO,IAAO,OAAA;EAAqB,SAAO,OAAO,UAAA;EAC3F,SAAA,MAAA,SAAA;EACG,SAAA,KAAA,EAAA,CAAA,OAAA,EASQ,MAAA,CAAO,MAAA,CAAO,IATtB,CAS2B,QAT3B,CAAA,EAAA,MAAA,EAS8C,OAT9C,CASsD,MAAA,CAAO,MAAA,CAAO,IATpE,CASyE,OATzE,CAAA,CAAA,EAAA,GAAA,IAAA;CACD"}
1
+ {"version":3,"file":"OperationDefinition.d.cts","names":[],"sources":["../src/OperationDefinition.ts"],"sourcesContent":[],"mappings":";;;;;;KAEK,aAAa,UAAU,yBAAyB,MAAM,6BAA6B,IAAI,EAAE;UAE7E,4CAA4C,MAAA,CAAO,qBAAqB,MAAA,CAAO;iBAC7E;oBACG;mBACD;EALhB,SAAA,YAAO,CAAA,EAAA,OAAA;;AAAgB,cASf,IATe,EAAA,CAAA,KAAA,EAAA,iBASiB,MAAA,CAAO,GATxB,EAAA,gBAS6C,MAAA,CAAO,GATpD,CAAA,CAAA,OAAA,EAAA;EAA+B,SAAA,IAAA,EAUxC,KAVwC;EAAN,SAAA,OAAA,EAW/B,QAX+B;EAAmC,SAAA,MAAA,EAYnE,OAZmE;EAAI,SAAA,KAAA,EAAA,CAAA,OAAA,EAa9D,MAAA,CAAO,MAAA,CAAO,IAbgD,CAa3C,QAb2C,CAAA,EAAA,MAAA,EAaxB,OAbwB,CAahB,MAAA,CAAO,MAAA,CAAO,IAbE,CAaG,OAbH,CAAA,CAAA,EAAA,GAAA,IAAA;EAAE,SAAA,YAAA,CAAA,EAAA,OAAA;CAAC,EAAA,GAAA;EAE9E,SAAA,YAAA,CAAmB,EAAA,OAAA,GAAA,SAAA;EAAyB,SAAO,IAAA,OAAA;EAAqB,SAAO,OAAA,UAAA;EAC7E,SAAA,MAAA,SAAA;EACG,SAAA,KAAA,EAAA,CAAA,OAAA,EASQ,MAAA,CAAO,MAAA,CAAO,IATtB,CAS2B,QAT3B,CAAA,EAAA,MAAA,EAS8C,OAT9C,CASsD,MAAA,CAAO,MAAA,CAAO,IATpE,CASyE,OATzE,CAAA,CAAA,EAAA,GAAA,IAAA;CACD"}
@@ -5,13 +5,13 @@ declare namespace OperationDefinition_d_exports {
5
5
  export { OperationDefinition, make };
6
6
  }
7
7
  type Mutable<T> = T extends ReadonlyArray<infer U> ? Array<U> : { -readonly [K in keyof T]: T[K] };
8
- interface OperationDefinition<TKind, TPayload extends Schema.Schema.Any, TTarget extends Schema.Schema.Any> {
8
+ interface OperationDefinition<TKind, TPayload extends Schema.Top, TTarget extends Schema.Top> {
9
9
  readonly kind: TKind;
10
10
  readonly payload: TPayload;
11
11
  readonly target: TTarget;
12
12
  readonly deduplicable?: boolean;
13
13
  }
14
- declare const make: <TKind, TPayload extends Schema.Schema.Any, TTarget extends Schema.Schema.Any>(options: {
14
+ declare const make: <TKind, TPayload extends Schema.Top, TTarget extends Schema.Top>(options: {
15
15
  readonly kind: TKind;
16
16
  readonly payload: TPayload;
17
17
  readonly target: TTarget;