[Snapping 1/5] Validation & strict types for fractional indexes (#2827)
Currently, we type our fractional index keys as `string` and don't have any validation for them. I'm touching some of this code for my work on line handles and wanted to change that: - fractional indexes are now `IndexKey`s, not `string`s. `IndexKey`s have a brand property so can't be used interchangeably with strings (like our IDs) - There's a new `T.indexKey` validator which we can use in our validations to make sure we don't end up with nonsense keys. This PR is part of a series - please don't merge it until the things before it have landed! 1. #2827 (you are here) 2. #2831 3. #2793 4. #2841 5. #2845 ### Change Type - [x] `patch` — Bug fix ### Test Plan 1. Mostly relying on unit & end to end tests here - no user facing changes. - [x] Unit Tests
This commit is contained in:
parent
fb00358a53
commit
93c2ed615c
40 changed files with 989 additions and 681 deletions
|
@ -790,6 +790,483 @@
|
|||
],
|
||||
"name": "getHashForString"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!getIndexAbove:function(1)",
|
||||
"docComment": "/**\n * Get the index above a given index.\n *\n * @param below - The index below.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function getIndexAbove(below: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 3,
|
||||
"endIndex": 4
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "below",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
],
|
||||
"name": "getIndexAbove"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!getIndexBelow:function(1)",
|
||||
"docComment": "/**\n * Get the index below a given index.\n *\n * @param above - The index above.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function getIndexBelow(above: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 3,
|
||||
"endIndex": 4
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "above",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
],
|
||||
"name": "getIndexBelow"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!getIndexBetween:function(1)",
|
||||
"docComment": "/**\n * Get the index between two indices.\n *\n * @param below - The index below.\n *\n * @param above - The index above.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function getIndexBetween(below: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", above?: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 5,
|
||||
"endIndex": 6
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "below",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "above",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 3,
|
||||
"endIndex": 4
|
||||
},
|
||||
"isOptional": true
|
||||
}
|
||||
],
|
||||
"name": "getIndexBetween"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!getIndices:function(1)",
|
||||
"docComment": "/**\n * Get n number of indices, starting at an index.\n *\n * @param n - The number of indices to get.\n *\n * @param start - The index to start at.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function getIndices(n: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "number"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", start?: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "[]"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 5,
|
||||
"endIndex": 7
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "n",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "start",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 3,
|
||||
"endIndex": 4
|
||||
},
|
||||
"isOptional": true
|
||||
}
|
||||
],
|
||||
"name": "getIndices"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!getIndicesAbove:function(1)",
|
||||
"docComment": "/**\n * Get a number of indices above an index.\n *\n * @param below - The index below.\n *\n * @param n - The number of indices to get.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function getIndicesAbove(below: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", n: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "number"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "[]"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 5,
|
||||
"endIndex": 7
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "below",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "n",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 3,
|
||||
"endIndex": 4
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
],
|
||||
"name": "getIndicesAbove"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!getIndicesBelow:function(1)",
|
||||
"docComment": "/**\n * Get a number of indices below an index.\n *\n * @param above - The index above.\n *\n * @param n - The number of indices to get.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function getIndicesBelow(above: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", n: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "number"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "[]"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 5,
|
||||
"endIndex": 7
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "above",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "n",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 3,
|
||||
"endIndex": 4
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
],
|
||||
"name": "getIndicesBelow"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!getIndicesBetween:function(1)",
|
||||
"docComment": "/**\n * Get a number of indices between two indices.\n *\n * @param below - The index below.\n *\n * @param above - The index above.\n *\n * @param n - The number of indices to get.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function getIndicesBetween(below: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | undefined"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", above: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | undefined"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", n: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "number"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "[]"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 9,
|
||||
"endIndex": 11
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "below",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 3
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "above",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 4,
|
||||
"endIndex": 6
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "n",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 7,
|
||||
"endIndex": 8
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
],
|
||||
"name": "getIndicesBetween"
|
||||
},
|
||||
{
|
||||
"kind": "TypeAlias",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type",
|
||||
"docComment": "/**\n * A string made up of an integer part followed by a fraction part. The fraction point consists of zero or more digits with no trailing zeros. Based on {@link https://observablehq.com/@dgreensp/implementing-fractional-indexing}.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export type IndexKey = "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "string & {\n __orderKey: true;\n}"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/IndexKey.ts",
|
||||
"releaseTag": "Public",
|
||||
"name": "IndexKey",
|
||||
"typeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!invLerp:function(1)",
|
||||
|
@ -2666,6 +3143,97 @@
|
|||
],
|
||||
"name": "sortById"
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/utils!sortByIndex:function(1)",
|
||||
"docComment": "/**\n * Sort by index.\n *\n * @param a - An object with an index property.\n *\n * @param b - An object with an index property.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export declare function sortByIndex<T extends "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "{\n index: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n}"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">(a: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "T"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", b: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "T"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "-1 | 0 | 1"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 9,
|
||||
"endIndex": 10
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "a",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 5,
|
||||
"endIndex": 6
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "b",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 7,
|
||||
"endIndex": 8
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
],
|
||||
"typeParameters": [
|
||||
{
|
||||
"typeParameterName": "T",
|
||||
"constraintTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 4
|
||||
},
|
||||
"defaultTypeTokenRange": {
|
||||
"startIndex": 0,
|
||||
"endIndex": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "sortByIndex"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"canonicalReference": "@tldraw/utils!structuredClone_2:var",
|
||||
|
@ -2788,6 +3356,30 @@
|
|||
}
|
||||
],
|
||||
"name": "throttle"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"canonicalReference": "@tldraw/utils!ZERO_INDEX_KEY:var",
|
||||
"docComment": "/**\n * The index key for the first index - 'a0'.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "ZERO_INDEX_KEY: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "IndexKey",
|
||||
"canonicalReference": "@tldraw/utils!IndexKey:type"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/utils/src/lib/reordering/reordering.ts",
|
||||
"isReadonly": true,
|
||||
"releaseTag": "Public",
|
||||
"name": "ZERO_INDEX_KEY",
|
||||
"variableTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue