@based/schema 5.0.0-alpha.20 → 5.0.0-alpha.22
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.
- package/dist/def/createEmptyDef.d.ts +9 -7
- package/dist/def/createEmptyDef.js +2 -0
- package/dist/def/defaultMap.js +1 -0
- package/dist/def/fillEmptyMain.d.ts +1 -1
- package/dist/def/selvaBuffer.js +10 -1
- package/dist/def/typeDef.d.ts +0 -1
- package/dist/def/typeDef.js +54 -16
- package/dist/def/types.d.ts +12 -0
- package/dist/def/types.js +6 -0
- package/dist/def/utils.js +4 -1
- package/dist/parse/index.js +1 -1
- package/dist/parse/props.js +10 -1
- package/dist/serialize.d.ts +11 -2
- package/dist/serialize.js +428 -80
- package/dist/types.d.ts +10 -1
- package/package.json +2 -3
|
@@ -2,13 +2,15 @@ import { SchemaLocales, SchemaObject, StrictSchemaType } from '../types.js';
|
|
|
2
2
|
export declare const createEmptyDef: (typeName: string, type: StrictSchemaType | SchemaObject, locales: Partial<SchemaLocales>) => {
|
|
3
3
|
cnt: number;
|
|
4
4
|
blockCapacity: number;
|
|
5
|
+
insertOnly: boolean;
|
|
6
|
+
partial: boolean;
|
|
5
7
|
checksum: number;
|
|
6
8
|
type: string;
|
|
7
9
|
props: {};
|
|
8
10
|
reverseProps: {};
|
|
9
|
-
idUint8: Uint8Array
|
|
11
|
+
idUint8: Uint8Array<ArrayBuffer>;
|
|
10
12
|
id: number;
|
|
11
|
-
mainEmpty: Uint8Array
|
|
13
|
+
mainEmpty: Uint8Array<ArrayBuffer>;
|
|
12
14
|
mainLen: number;
|
|
13
15
|
separate: any[];
|
|
14
16
|
tree: {};
|
|
@@ -23,16 +25,16 @@ export declare const createEmptyDef: (typeName: string, type: StrictSchemaType |
|
|
|
23
25
|
seperateSort: {
|
|
24
26
|
size: number;
|
|
25
27
|
props: any[];
|
|
26
|
-
buffer: Uint8Array
|
|
27
|
-
bufferTmp: Uint8Array
|
|
28
|
+
buffer: Uint8Array<ArrayBuffer>;
|
|
29
|
+
bufferTmp: Uint8Array<ArrayBuffer>;
|
|
28
30
|
};
|
|
29
31
|
hasSeperateTextSort: boolean;
|
|
30
32
|
seperateTextSort: {
|
|
31
33
|
size: number;
|
|
32
34
|
props: any[];
|
|
33
|
-
buffer: Uint8Array
|
|
34
|
-
noUndefined: Uint8Array
|
|
35
|
-
bufferTmp: Uint8Array
|
|
35
|
+
buffer: Uint8Array<ArrayBuffer>;
|
|
36
|
+
noUndefined: Uint8Array<ArrayBuffer>;
|
|
37
|
+
bufferTmp: Uint8Array<ArrayBuffer>;
|
|
36
38
|
localeStringToIndex: Map<any, any>;
|
|
37
39
|
localeToIndex: Map<any, any>;
|
|
38
40
|
};
|
package/dist/def/defaultMap.js
CHANGED
|
@@ -23,5 +23,6 @@ export const DEFAULT_MAP = {
|
|
|
23
23
|
[TYPE_INDEX_MAP.aliases]: [],
|
|
24
24
|
[TYPE_INDEX_MAP.text]: {},
|
|
25
25
|
[TYPE_INDEX_MAP.vector]: undefined, // maybe not can set a vec with 0
|
|
26
|
+
[TYPE_INDEX_MAP.colvec]: undefined, // maybe not can set a vec with 0
|
|
26
27
|
};
|
|
27
28
|
//# sourceMappingURL=defaultMap.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PropDef } from './types.js';
|
|
2
2
|
export declare const ENCODER: TextEncoder;
|
|
3
|
-
export declare const fillEmptyMain: (vals: PropDef[], mainLen: number) => Uint8Array
|
|
3
|
+
export declare const fillEmptyMain: (vals: PropDef[], mainLen: number) => Uint8Array<ArrayBuffer>;
|
|
4
4
|
export declare const isZeroes: (buf: Uint8Array) => boolean;
|
|
5
5
|
//# sourceMappingURL=fillEmptyMain.d.ts.map
|
package/dist/def/selvaBuffer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ALIAS, ALIASES, BINARY, EMPTY_MICRO_BUFFER, CARDINALITY, MICRO_BUFFER, REFERENCE, REFERENCES, STRING, TEXT, VECTOR, WEAK_REFERENCE, WEAK_REFERENCES, JSON, } from './types.js';
|
|
1
|
+
import { ALIAS, ALIASES, BINARY, EMPTY_MICRO_BUFFER, CARDINALITY, MICRO_BUFFER, REFERENCE, REFERENCES, STRING, TEXT, VECTOR, WEAK_REFERENCE, WEAK_REFERENCES, JSON, COLVEC, } from './types.js';
|
|
2
2
|
const selvaFieldType = {
|
|
3
3
|
NULL: 0,
|
|
4
4
|
MICRO_BUFFER: 1,
|
|
@@ -26,6 +26,7 @@ selvaTypeMap[WEAK_REFERENCE] = selvaFieldType.WEAK_REFERENCE;
|
|
|
26
26
|
selvaTypeMap[WEAK_REFERENCES] = selvaFieldType.WEAK_REFERENCES;
|
|
27
27
|
selvaTypeMap[ALIAS] = selvaFieldType.ALIAS;
|
|
28
28
|
selvaTypeMap[ALIASES] = selvaFieldType.ALIASES;
|
|
29
|
+
selvaTypeMap[COLVEC] = selvaFieldType.COLVEC;
|
|
29
30
|
const EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT = 0x01;
|
|
30
31
|
const EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP = 0x80;
|
|
31
32
|
function blockCapacity(blockCapacity) {
|
|
@@ -53,6 +54,14 @@ const propDefBuffer = (schema, prop, isEdge) => {
|
|
|
53
54
|
view.setUint16(1, prop.len, true);
|
|
54
55
|
return [...buf];
|
|
55
56
|
}
|
|
57
|
+
else if (prop.len && (type === COLVEC)) {
|
|
58
|
+
const buf = new Uint8Array(5);
|
|
59
|
+
const view = new DataView(buf.buffer);
|
|
60
|
+
buf[0] = selvaType;
|
|
61
|
+
view.setUint16(1, prop.len, true);
|
|
62
|
+
view.setUint16(3, 4, true); // TODO Other types than f32
|
|
63
|
+
return [...buf];
|
|
64
|
+
}
|
|
56
65
|
else if (type === REFERENCE || type === REFERENCES) {
|
|
57
66
|
const buf = new Uint8Array(9);
|
|
58
67
|
const view = new DataView(buf.buffer);
|
package/dist/def/typeDef.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { SchemaObject, StrictSchemaType, SchemaLocales } from '../index.js';
|
|
2
2
|
import { SchemaTypeDef, SchemaTypesParsed } from './types.js';
|
|
3
3
|
import { StrictSchema } from '../types.js';
|
|
4
|
-
export declare const DEFAULT_BLOCK_CAPACITY = 100000;
|
|
5
4
|
export declare const updateTypeDefs: (schema: StrictSchema) => {
|
|
6
5
|
schemaTypesParsed: {
|
|
7
6
|
[key: string]: SchemaTypeDef;
|
package/dist/def/typeDef.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isPropType, getPropType, } from '../index.js';
|
|
2
2
|
import { setByPath } from '@saulx/utils';
|
|
3
|
-
import { TYPE_INDEX_MAP, REFERENCES, REFERENCE, NUMBER, } from './types.js';
|
|
3
|
+
import { TYPE_INDEX_MAP, REFERENCES, REFERENCE, NUMBER, BLOCK_CAPACITY_MAX, BLOCK_CAPACITY_DEFAULT, BLOCK_CAPACITY_MIN, } from './types.js';
|
|
4
4
|
import { DEFAULT_MAP } from './defaultMap.js';
|
|
5
5
|
import { makeSeparateTextSort } from './makeSeparateTextSort.js';
|
|
6
6
|
import { makeSeparateSort } from './makeSeparateSort.js';
|
|
@@ -9,39 +9,59 @@ import { addEdges } from './addEdges.js';
|
|
|
9
9
|
import { createEmptyDef } from './createEmptyDef.js';
|
|
10
10
|
import { fillEmptyMain, isZeroes } from './fillEmptyMain.js';
|
|
11
11
|
import { defaultValidation, VALIDATION_MAP } from './validation.js';
|
|
12
|
-
export const DEFAULT_BLOCK_CAPACITY = 100_000;
|
|
13
12
|
export const updateTypeDefs = (schema) => {
|
|
14
13
|
const schemaTypesParsed = {};
|
|
15
14
|
const schemaTypesParsedById = {};
|
|
16
|
-
for (const
|
|
17
|
-
if (
|
|
15
|
+
for (const typeName in schemaTypesParsed) {
|
|
16
|
+
if (typeName in schema.types) {
|
|
18
17
|
continue;
|
|
19
18
|
}
|
|
20
|
-
const id = schemaTypesParsed[
|
|
21
|
-
delete schemaTypesParsed[
|
|
19
|
+
const id = schemaTypesParsed[typeName].id;
|
|
20
|
+
delete schemaTypesParsed[typeName];
|
|
22
21
|
delete schemaTypesParsedById[id];
|
|
23
22
|
}
|
|
24
|
-
for (const
|
|
25
|
-
const type = schema.types[
|
|
23
|
+
for (const typeName in schema.types) {
|
|
24
|
+
const type = schema.types[typeName];
|
|
26
25
|
if (!type.id) {
|
|
27
26
|
throw new Error('NEED ID ON TYPE');
|
|
28
27
|
}
|
|
29
|
-
const def = createSchemaTypeDef(
|
|
28
|
+
const def = createSchemaTypeDef(typeName, type, schemaTypesParsed, schema.locales ?? {
|
|
30
29
|
en: {},
|
|
31
30
|
});
|
|
32
|
-
|
|
33
|
-
schemaTypesParsed[field] = def;
|
|
31
|
+
schemaTypesParsed[typeName] = def;
|
|
34
32
|
schemaTypesParsedById[type.id] = def;
|
|
35
33
|
}
|
|
36
34
|
return { schemaTypesParsed, schemaTypesParsedById };
|
|
37
35
|
};
|
|
38
36
|
export const createSchemaTypeDef = (typeName, type, parsed, locales, result = createEmptyDef(typeName, type, locales), path = [], top = true) => {
|
|
39
|
-
if (
|
|
40
|
-
if (
|
|
41
|
-
|
|
37
|
+
if (top) {
|
|
38
|
+
if (result.id == 0) {
|
|
39
|
+
if ('id' in type) {
|
|
40
|
+
result.id = type.id;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new Error(`Invalid schema type id ${result.type}`);
|
|
44
|
+
}
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
if (result.blockCapacity == 0) {
|
|
47
|
+
if ('blockCapacity' in type) {
|
|
48
|
+
if (typeof type.blockCapacity !== 'number' ||
|
|
49
|
+
type.blockCapacity < BLOCK_CAPACITY_MIN ||
|
|
50
|
+
type.blockCapacity > BLOCK_CAPACITY_MAX) {
|
|
51
|
+
throw new Error('Invalid blockCapacity');
|
|
52
|
+
}
|
|
53
|
+
result.blockCapacity = type.blockCapacity;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
result.blockCapacity =
|
|
57
|
+
typeName === '_root' ? BLOCK_CAPACITY_MAX : BLOCK_CAPACITY_DEFAULT;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (result.insertOnly == false && 'insertOnly' in type) {
|
|
61
|
+
result.insertOnly = !!type.insertOnly;
|
|
62
|
+
}
|
|
63
|
+
if (result.partial == false && 'partial' in type) {
|
|
64
|
+
result.partial = !!type.partial;
|
|
45
65
|
}
|
|
46
66
|
}
|
|
47
67
|
result.locales = locales;
|
|
@@ -75,6 +95,11 @@ export const createSchemaTypeDef = (typeName, type, parsed, locales, result = cr
|
|
|
75
95
|
else if (isPropType('text', schemaProp)) {
|
|
76
96
|
result.separateSortText++;
|
|
77
97
|
}
|
|
98
|
+
else if (isPropType('colvec', schemaProp)) {
|
|
99
|
+
if (!result.insertOnly) {
|
|
100
|
+
throw new Error('colvec requires insertOnly');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
78
103
|
const isseparate = isSeparate(schemaProp, len);
|
|
79
104
|
const typeIndex = TYPE_INDEX_MAP[propType];
|
|
80
105
|
const prop = {
|
|
@@ -110,12 +135,18 @@ export const createSchemaTypeDef = (typeName, type, parsed, locales, result = cr
|
|
|
110
135
|
}
|
|
111
136
|
}
|
|
112
137
|
else if (isPropType('references', schemaProp)) {
|
|
138
|
+
if (result.partial) {
|
|
139
|
+
throw new Error('references is not supported with partial');
|
|
140
|
+
}
|
|
113
141
|
prop.inversePropName = schemaProp.items.prop;
|
|
114
142
|
prop.inverseTypeName = schemaProp.items.ref;
|
|
115
143
|
prop.dependent = schemaProp.items.dependent;
|
|
116
144
|
addEdges(prop, schemaProp.items);
|
|
117
145
|
}
|
|
118
146
|
else if (isPropType('reference', schemaProp)) {
|
|
147
|
+
if (result.partial) {
|
|
148
|
+
throw new Error('reference is not supported with partial');
|
|
149
|
+
}
|
|
119
150
|
prop.inversePropName = schemaProp.prop;
|
|
120
151
|
prop.inverseTypeName = schemaProp.ref;
|
|
121
152
|
prop.dependent = schemaProp.dependent;
|
|
@@ -169,6 +200,13 @@ export const createSchemaTypeDef = (typeName, type, parsed, locales, result = cr
|
|
|
169
200
|
if (f.separate) {
|
|
170
201
|
len += 2;
|
|
171
202
|
setByPath(result.tree, f.path, f);
|
|
203
|
+
if (f.default !== undefined) {
|
|
204
|
+
result.hasSeperateDefaults = true;
|
|
205
|
+
if (!result.seperateDefaults) {
|
|
206
|
+
// result.seperateDefaults = []
|
|
207
|
+
}
|
|
208
|
+
// result.seperateDefaults.push(f)
|
|
209
|
+
}
|
|
172
210
|
}
|
|
173
211
|
else {
|
|
174
212
|
if (!result.mainLen) {
|
package/dist/def/types.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare const ID = 26;
|
|
|
26
26
|
export declare const VECTOR = 27;
|
|
27
27
|
export declare const JSON = 28;
|
|
28
28
|
export declare const OBJECT = 29;
|
|
29
|
+
export declare const COLVEC = 30;
|
|
29
30
|
export declare const TYPE_INDEX_MAP: {
|
|
30
31
|
alias: number;
|
|
31
32
|
aliases: number;
|
|
@@ -50,6 +51,7 @@ export declare const TYPE_INDEX_MAP: {
|
|
|
50
51
|
cardinality: number;
|
|
51
52
|
json: number;
|
|
52
53
|
object: number;
|
|
54
|
+
colvec: number;
|
|
53
55
|
};
|
|
54
56
|
export declare const enum numberTypes {
|
|
55
57
|
number = 4,
|
|
@@ -126,6 +128,9 @@ export type SchemaSortUndefinedHandler = {
|
|
|
126
128
|
bufferTmp: Uint8Array;
|
|
127
129
|
props: PropDef[];
|
|
128
130
|
};
|
|
131
|
+
export declare const BLOCK_CAPACITY_MIN = 1025;
|
|
132
|
+
export declare const BLOCK_CAPACITY_MAX = 2147483647;
|
|
133
|
+
export declare const BLOCK_CAPACITY_DEFAULT = 100000;
|
|
129
134
|
export type SchemaTypeDef = {
|
|
130
135
|
cnt: number;
|
|
131
136
|
checksum: number;
|
|
@@ -133,6 +138,8 @@ export type SchemaTypeDef = {
|
|
|
133
138
|
lastId: number;
|
|
134
139
|
blockCapacity: number;
|
|
135
140
|
mainLen: number;
|
|
141
|
+
insertOnly: boolean;
|
|
142
|
+
partial: boolean;
|
|
136
143
|
buf: Uint8Array;
|
|
137
144
|
propNames: Uint8Array;
|
|
138
145
|
props: {
|
|
@@ -160,6 +167,11 @@ export type SchemaTypeDef = {
|
|
|
160
167
|
localeStringToIndex: Map<string, Uint8Array>;
|
|
161
168
|
localeToIndex: Map<LangCode, number>;
|
|
162
169
|
};
|
|
170
|
+
hasSeperateDefaults: boolean;
|
|
171
|
+
seperateDefaults?: {
|
|
172
|
+
props: Map<number, PropDef>;
|
|
173
|
+
bufferTmp: Uint8Array;
|
|
174
|
+
};
|
|
163
175
|
createTs?: PropDef[];
|
|
164
176
|
updateTs?: PropDef[];
|
|
165
177
|
locales: Partial<SchemaLocales>;
|
package/dist/def/types.js
CHANGED
|
@@ -25,6 +25,7 @@ export const ID = 26;
|
|
|
25
25
|
export const VECTOR = 27;
|
|
26
26
|
export const JSON = 28;
|
|
27
27
|
export const OBJECT = 29;
|
|
28
|
+
export const COLVEC = 30;
|
|
28
29
|
export const TYPE_INDEX_MAP = {
|
|
29
30
|
alias: ALIAS,
|
|
30
31
|
aliases: ALIASES,
|
|
@@ -49,6 +50,7 @@ export const TYPE_INDEX_MAP = {
|
|
|
49
50
|
cardinality: CARDINALITY,
|
|
50
51
|
json: JSON,
|
|
51
52
|
object: OBJECT,
|
|
53
|
+
colvec: COLVEC,
|
|
52
54
|
};
|
|
53
55
|
const numberTypeValues = [
|
|
54
56
|
NUMBER,
|
|
@@ -63,6 +65,9 @@ const numberTypeValues = [
|
|
|
63
65
|
export function isNumberType(type) {
|
|
64
66
|
return numberTypeValues.includes(type);
|
|
65
67
|
}
|
|
68
|
+
export const BLOCK_CAPACITY_MIN = 1025;
|
|
69
|
+
export const BLOCK_CAPACITY_MAX = 2147483647;
|
|
70
|
+
export const BLOCK_CAPACITY_DEFAULT = 100_000;
|
|
66
71
|
export const SIZE_MAP = {
|
|
67
72
|
timestamp: 8, // 64bit
|
|
68
73
|
// double-precision 64-bit binary format IEEE 754 value
|
|
@@ -88,6 +93,7 @@ export const SIZE_MAP = {
|
|
|
88
93
|
vector: 0, // separate
|
|
89
94
|
json: 0,
|
|
90
95
|
object: 0,
|
|
96
|
+
colvec: 0, // separate
|
|
91
97
|
};
|
|
92
98
|
const reverseMap = {};
|
|
93
99
|
for (const k in TYPE_INDEX_MAP) {
|
package/dist/def/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ import { isPropType } from '../types.js';
|
|
|
3
3
|
import { getPropType } from '../parse/utils.js';
|
|
4
4
|
import { convertToTimestamp } from '@saulx/utils';
|
|
5
5
|
export function isSeparate(schemaProp, len) {
|
|
6
|
-
return len === 0 || isPropType('vector', schemaProp);
|
|
6
|
+
return len === 0 || isPropType('vector', schemaProp) || isPropType('colvec', schemaProp);
|
|
7
7
|
}
|
|
8
8
|
export const propIsSigned = (prop) => {
|
|
9
9
|
const t = prop.typeIndex;
|
|
@@ -43,6 +43,9 @@ export function getPropLen(schemaProp) {
|
|
|
43
43
|
else if (isPropType('vector', schemaProp)) {
|
|
44
44
|
len = 4 * schemaProp.size;
|
|
45
45
|
}
|
|
46
|
+
else if (isPropType('colvec', schemaProp)) {
|
|
47
|
+
len = schemaProp.size;
|
|
48
|
+
}
|
|
46
49
|
return len;
|
|
47
50
|
}
|
|
48
51
|
export const parseMinMaxStep = (val) => {
|
package/dist/parse/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { deepCopy } from '@saulx/utils';
|
|
|
7
7
|
export { getPropType };
|
|
8
8
|
export class SchemaParser {
|
|
9
9
|
constructor(schema) {
|
|
10
|
+
// uint8Array is not working
|
|
10
11
|
this.schema = deepCopy(schema);
|
|
11
12
|
}
|
|
12
13
|
isItems;
|
|
@@ -65,7 +66,6 @@ export class SchemaParser {
|
|
|
65
66
|
for (const locale in locales) {
|
|
66
67
|
const opts = locales[locale];
|
|
67
68
|
if (opts === true) {
|
|
68
|
-
console.log(locale, opts);
|
|
69
69
|
continue;
|
|
70
70
|
}
|
|
71
71
|
expectObject(opts);
|
package/dist/parse/props.js
CHANGED
|
@@ -128,7 +128,7 @@ export const isDefault = (val, prop, ctx) => {
|
|
|
128
128
|
enum: prop.enum,
|
|
129
129
|
validation,
|
|
130
130
|
default: DEFAULT_MAP[typeIndex],
|
|
131
|
-
step: parseMinMaxStep(prop.step ?? typeIndex === NUMBER ? 0 : 1),
|
|
131
|
+
step: parseMinMaxStep((prop.step ?? typeIndex === NUMBER) ? 0 : 1),
|
|
132
132
|
max: parseMinMaxStep(prop.max),
|
|
133
133
|
min: parseMinMaxStep(prop.min),
|
|
134
134
|
};
|
|
@@ -157,6 +157,15 @@ p.vector = propParser({
|
|
|
157
157
|
return isDefault(val, prop, ctx);
|
|
158
158
|
},
|
|
159
159
|
}, 0);
|
|
160
|
+
p.colvec = propParser({
|
|
161
|
+
size(val) {
|
|
162
|
+
expectNumber(val);
|
|
163
|
+
},
|
|
164
|
+
}, {
|
|
165
|
+
default(val, prop, ctx) {
|
|
166
|
+
return isDefault(val, prop, ctx);
|
|
167
|
+
},
|
|
168
|
+
}, 0);
|
|
160
169
|
p.enum = propParser({
|
|
161
170
|
enum(items) {
|
|
162
171
|
if (!Array.isArray(items)) {
|
package/dist/serialize.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { StrictSchema } from './types.js';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
type Opts = {
|
|
3
|
+
readOnly?: boolean;
|
|
4
|
+
stripMetaInformation?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare const serialize: (schema: any, opts?: Opts) => Uint8Array;
|
|
7
|
+
export declare const deSerializeKey: (buf: Uint8Array, keySize: number, i: number) => {
|
|
8
|
+
size: number;
|
|
9
|
+
value: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const deSerializeInner: (buf: Uint8Array, obj: any, start: number, fromArray: boolean) => number;
|
|
4
12
|
export declare const deSerialize: (buf: Uint8Array) => StrictSchema;
|
|
13
|
+
export {};
|
|
5
14
|
//# sourceMappingURL=serialize.d.ts.map
|
package/dist/serialize.js
CHANGED
|
@@ -1,142 +1,490 @@
|
|
|
1
|
-
import * as deflate from 'fflate'
|
|
2
|
-
import {
|
|
1
|
+
// import * as deflate from 'fflate'
|
|
2
|
+
import { stringFormats } from './types.js';
|
|
3
|
+
import { ENUM, REVERSE_TYPE_INDEX_MAP, TYPE_INDEX_MAP } from './def/types.js';
|
|
4
|
+
import { readDoubleLE, readUint16, readUint24, readUint32, writeDoubleLE, writeUint16, writeUint24, writeUint32, } from '@saulx/utils';
|
|
3
5
|
const ENCODER = new TextEncoder();
|
|
6
|
+
const UINT8 = 245;
|
|
7
|
+
const FALSE = 246;
|
|
8
|
+
const TRUE = 247;
|
|
9
|
+
const FUNCTION = 248;
|
|
10
|
+
const STRING = 249;
|
|
11
|
+
const ARRAY = 250;
|
|
12
|
+
const BINARY = 251;
|
|
13
|
+
const UINT32 = 252;
|
|
14
|
+
const FLOAT64 = 253;
|
|
15
|
+
const SCHEMA_PROP = 254;
|
|
16
|
+
const OBJECT = 255;
|
|
17
|
+
// Key Address encoding types
|
|
18
|
+
const KEY_ADDRESS_1_BYTE = 0;
|
|
19
|
+
const KEY_ADDRESS_2_BYTES = 1;
|
|
20
|
+
const KEY_ADDRESS_3_BYTES = 2;
|
|
21
|
+
// Key types
|
|
22
|
+
const PROPS = 3;
|
|
23
|
+
const TYPES = 4;
|
|
24
|
+
const READONLY = 5;
|
|
25
|
+
const FORMAT = 6;
|
|
26
|
+
const REQUIRED = 7;
|
|
27
|
+
const REF = 8;
|
|
28
|
+
const PROP = 9;
|
|
29
|
+
const KEY_OPTS = PROP;
|
|
30
|
+
const ensureCapacity = (required) => {
|
|
31
|
+
if (schemaBuffer.len + required > schemaBuffer.buf.length) {
|
|
32
|
+
const newBuf = new Uint8Array(Math.max(schemaBuffer.buf.length * 2, schemaBuffer.len + required));
|
|
33
|
+
newBuf.set(schemaBuffer.buf);
|
|
34
|
+
schemaBuffer.buf = newBuf;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
4
37
|
let schemaBuffer;
|
|
38
|
+
const handleSingleValue = (ops, val, obj, prev, fromObject, key) => {
|
|
39
|
+
const type = typeof val;
|
|
40
|
+
// typed Array - single PROP
|
|
41
|
+
if (val instanceof Uint8Array) {
|
|
42
|
+
ensureCapacity(1 + 2 + val.byteLength);
|
|
43
|
+
schemaBuffer.buf[schemaBuffer.len] = BINARY;
|
|
44
|
+
schemaBuffer.len += 1;
|
|
45
|
+
schemaBuffer.buf[schemaBuffer.len] = val.byteLength;
|
|
46
|
+
schemaBuffer.len += 1;
|
|
47
|
+
schemaBuffer.buf[schemaBuffer.len] = val.byteLength >>> 8;
|
|
48
|
+
schemaBuffer.len += 1;
|
|
49
|
+
schemaBuffer.buf.set(val, schemaBuffer.len);
|
|
50
|
+
schemaBuffer.len += val.byteLength;
|
|
51
|
+
}
|
|
52
|
+
else if (type === 'function') {
|
|
53
|
+
const str = val.toString();
|
|
54
|
+
// Pessimistically assume 4 bytes per char for UTF-8 to be safe.
|
|
55
|
+
ensureCapacity(1 + 2 + str.length * 4);
|
|
56
|
+
schemaBuffer.buf[schemaBuffer.len] = FUNCTION;
|
|
57
|
+
schemaBuffer.len += 1;
|
|
58
|
+
const sizeIndex = schemaBuffer.len;
|
|
59
|
+
schemaBuffer.len += 2;
|
|
60
|
+
// encodeInto is much faster as it avoids intermediate allocation.
|
|
61
|
+
const r = ENCODER.encodeInto(str, schemaBuffer.buf.subarray(schemaBuffer.len));
|
|
62
|
+
schemaBuffer.len += r.written;
|
|
63
|
+
schemaBuffer.buf[sizeIndex] = r.written;
|
|
64
|
+
schemaBuffer.buf[sizeIndex + 1] = r.written >>> 8;
|
|
65
|
+
}
|
|
66
|
+
else if (type === 'object') {
|
|
67
|
+
// fromObject
|
|
68
|
+
if (val === null) {
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (!fromObject && key === 'props' && obj.type === 'object') {
|
|
72
|
+
walk(ops, val, obj, prev, true, schemaBuffer);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
walk(ops, val, obj, prev, fromObject, schemaBuffer);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (type === 'boolean') {
|
|
80
|
+
ensureCapacity(1);
|
|
81
|
+
schemaBuffer.buf[schemaBuffer.len] = val ? TRUE : FALSE;
|
|
82
|
+
schemaBuffer.len += 1;
|
|
83
|
+
}
|
|
84
|
+
else if (type === 'string') {
|
|
85
|
+
// Pessimistically assume 4 bytes per char for UTF-8 to be safe.
|
|
86
|
+
ensureCapacity(1 + 2 + val.length * 4);
|
|
87
|
+
schemaBuffer.buf[schemaBuffer.len] = STRING;
|
|
88
|
+
schemaBuffer.len += 1;
|
|
89
|
+
const sizeIndex = schemaBuffer.len;
|
|
90
|
+
schemaBuffer.len += 2;
|
|
91
|
+
// encodeInto is much faster as it avoids intermediate allocation.
|
|
92
|
+
const r = ENCODER.encodeInto(val, schemaBuffer.buf.subarray(schemaBuffer.len));
|
|
93
|
+
schemaBuffer.len += r.written;
|
|
94
|
+
schemaBuffer.buf[sizeIndex] = r.written;
|
|
95
|
+
schemaBuffer.buf[sizeIndex + 1] = r.written >>> 8;
|
|
96
|
+
}
|
|
97
|
+
else if (type === 'number') {
|
|
98
|
+
const isInt = val % 1 === 0;
|
|
99
|
+
if (val < 256 && val > 0 && isInt) {
|
|
100
|
+
ensureCapacity(2);
|
|
101
|
+
schemaBuffer.buf[schemaBuffer.len] = UINT8;
|
|
102
|
+
schemaBuffer.len += 1;
|
|
103
|
+
schemaBuffer.buf[schemaBuffer.len] = val;
|
|
104
|
+
schemaBuffer.len += 1;
|
|
105
|
+
}
|
|
106
|
+
else if ((val < 4294967295 || val > 0) && isInt) {
|
|
107
|
+
ensureCapacity(5);
|
|
108
|
+
schemaBuffer.buf[schemaBuffer.len] = UINT32;
|
|
109
|
+
schemaBuffer.len += 1;
|
|
110
|
+
writeUint32(schemaBuffer.buf, val, schemaBuffer.len);
|
|
111
|
+
schemaBuffer.len += 4;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
ensureCapacity(9);
|
|
115
|
+
schemaBuffer.buf[schemaBuffer.len] = FLOAT64;
|
|
116
|
+
schemaBuffer.len += 1;
|
|
117
|
+
writeDoubleLE(schemaBuffer.buf, val, schemaBuffer.len);
|
|
118
|
+
schemaBuffer.len += 8;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const encodeKey = (key, schemaBuffer) => {
|
|
123
|
+
let address = schemaBuffer.dictMap[key];
|
|
124
|
+
// if len == 1 never from address
|
|
125
|
+
if (!address) {
|
|
126
|
+
// pessimistically assume 4 bytes per char for UTF-8 to be safe.
|
|
127
|
+
ensureCapacity(1 + key.length * 4);
|
|
128
|
+
address = schemaBuffer.len;
|
|
129
|
+
schemaBuffer.len += 1;
|
|
130
|
+
const r = ENCODER.encodeInto(key, schemaBuffer.buf.subarray(schemaBuffer.len));
|
|
131
|
+
schemaBuffer.buf[address] = r.written + KEY_OPTS;
|
|
132
|
+
schemaBuffer.len += r.written;
|
|
133
|
+
schemaBuffer.dictMap[key] = address;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
ensureCapacity(4);
|
|
137
|
+
if (address > 65025) {
|
|
138
|
+
schemaBuffer.buf[schemaBuffer.len] = KEY_ADDRESS_3_BYTES;
|
|
139
|
+
schemaBuffer.len += 1;
|
|
140
|
+
writeUint24(schemaBuffer.buf, address, schemaBuffer.len);
|
|
141
|
+
schemaBuffer.len += 3;
|
|
142
|
+
}
|
|
143
|
+
else if (address > 255) {
|
|
144
|
+
schemaBuffer.buf[schemaBuffer.len] = KEY_ADDRESS_2_BYTES;
|
|
145
|
+
schemaBuffer.len += 1;
|
|
146
|
+
writeUint16(schemaBuffer.buf, address, schemaBuffer.len);
|
|
147
|
+
schemaBuffer.len += 2;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
schemaBuffer.buf[schemaBuffer.len] = KEY_ADDRESS_1_BYTE;
|
|
151
|
+
schemaBuffer.len += 1;
|
|
152
|
+
schemaBuffer.buf[schemaBuffer.len] = address;
|
|
153
|
+
schemaBuffer.len += 1;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
5
157
|
// 3 level
|
|
6
158
|
// 0 for queries (min)
|
|
7
159
|
// 1 for modify
|
|
8
160
|
// 2 fulls schema
|
|
9
|
-
const walk = (obj, prev, prev2, fromObject, schemaBuffer) => {
|
|
161
|
+
const walk = (opts, obj, prev, prev2, fromObject, schemaBuffer) => {
|
|
10
162
|
let start = schemaBuffer.len;
|
|
11
|
-
|
|
12
|
-
const
|
|
163
|
+
const isArray = Array.isArray(obj);
|
|
164
|
+
const isFromObj = prev2?.type === 'object' || fromObject === false;
|
|
165
|
+
const isSchemaProp = ('enum' in obj || ('type' in obj && TYPE_INDEX_MAP[obj.type])) && isFromObj;
|
|
166
|
+
ensureCapacity(1 + 5); // Type byte + size
|
|
13
167
|
if (isSchemaProp) {
|
|
14
|
-
schemaBuffer.buf[schemaBuffer.len++] =
|
|
15
|
-
const typeIndex = TYPE_INDEX_MAP[obj.type];
|
|
168
|
+
schemaBuffer.buf[schemaBuffer.len++] = SCHEMA_PROP;
|
|
169
|
+
const typeIndex = TYPE_INDEX_MAP['enum' in obj ? 'enum' : obj.type];
|
|
16
170
|
schemaBuffer.buf[schemaBuffer.len++] = typeIndex;
|
|
17
171
|
}
|
|
18
172
|
else {
|
|
19
|
-
schemaBuffer.buf[schemaBuffer.len++] =
|
|
173
|
+
schemaBuffer.buf[schemaBuffer.len++] = isArray ? ARRAY : OBJECT;
|
|
20
174
|
}
|
|
21
175
|
let sizeIndex = schemaBuffer.len;
|
|
22
|
-
schemaBuffer.len +=
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
address = schemaBuffer.len;
|
|
176
|
+
schemaBuffer.len += 5;
|
|
177
|
+
if (isArray) {
|
|
178
|
+
const len = obj.length;
|
|
179
|
+
ensureCapacity(2 * len + 2);
|
|
180
|
+
writeUint16(schemaBuffer.buf, len, schemaBuffer.len);
|
|
181
|
+
schemaBuffer.len += 2;
|
|
182
|
+
for (let j = 0; j < len; j++) {
|
|
183
|
+
if (len < 256) {
|
|
184
|
+
schemaBuffer.buf[schemaBuffer.len] = j;
|
|
32
185
|
schemaBuffer.len += 1;
|
|
33
|
-
const r = ENCODER.encodeInto(key, schemaBuffer.buf.subarray(schemaBuffer.len));
|
|
34
|
-
schemaBuffer.buf[address] = r.written;
|
|
35
|
-
schemaBuffer.len += r.written;
|
|
36
|
-
schemaBuffer.dictMap[key] = address;
|
|
37
186
|
}
|
|
38
187
|
else {
|
|
39
|
-
schemaBuffer.buf
|
|
40
|
-
schemaBuffer.len += 1;
|
|
41
|
-
schemaBuffer.buf[schemaBuffer.len] = address;
|
|
42
|
-
schemaBuffer.buf[schemaBuffer.len + 1] = address >>> 8;
|
|
188
|
+
writeUint16(schemaBuffer.buf, j, schemaBuffer.len);
|
|
43
189
|
schemaBuffer.len += 2;
|
|
44
190
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
191
|
+
handleSingleValue(opts, obj[j], obj, prev, fromObject, j);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
for (const key in obj) {
|
|
196
|
+
if (opts.readOnly &&
|
|
197
|
+
isFromObj &&
|
|
198
|
+
(key === 'validation' || key === 'default')) {
|
|
199
|
+
if (key === 'validation' && typeof obj[key] === 'function') {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
else if (key === 'default') {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
50
205
|
}
|
|
51
|
-
else if (
|
|
52
|
-
|
|
206
|
+
else if (isFromObj &&
|
|
207
|
+
(opts.stripMetaInformation || opts.readOnly) &&
|
|
208
|
+
(key === 'title' ||
|
|
209
|
+
key === 'description' ||
|
|
210
|
+
key === 'format' ||
|
|
211
|
+
key === 'display') &&
|
|
212
|
+
typeof obj[key] === 'string') {
|
|
213
|
+
continue;
|
|
53
214
|
}
|
|
54
|
-
else if (
|
|
55
|
-
|
|
56
|
-
|
|
215
|
+
else if (key === 'type' && isSchemaProp) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
else if (key === 'required' && obj[key] === true) {
|
|
219
|
+
ensureCapacity(1);
|
|
220
|
+
schemaBuffer.buf[schemaBuffer.len] = REQUIRED;
|
|
221
|
+
schemaBuffer.len += 1;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
// Add this later
|
|
225
|
+
else if (key == 'ref' && isFromObj && typeof obj.ref === 'string') {
|
|
226
|
+
ensureCapacity(1);
|
|
227
|
+
schemaBuffer.buf[schemaBuffer.len] = REF;
|
|
228
|
+
schemaBuffer.len += 1;
|
|
229
|
+
encodeKey(obj[key], schemaBuffer);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
else if (key === 'prop' && isFromObj && typeof obj.prop === 'string') {
|
|
233
|
+
ensureCapacity(1);
|
|
234
|
+
schemaBuffer.buf[schemaBuffer.len] = PROP;
|
|
235
|
+
schemaBuffer.len += 1;
|
|
236
|
+
encodeKey(obj[key], schemaBuffer);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
else if (key === 'readOnly' && obj[key] === true) {
|
|
240
|
+
ensureCapacity(1);
|
|
241
|
+
schemaBuffer.buf[schemaBuffer.len] = READONLY;
|
|
242
|
+
schemaBuffer.len += 1;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
else if (key === 'format' && isFromObj) {
|
|
246
|
+
ensureCapacity(2);
|
|
247
|
+
schemaBuffer.buf[schemaBuffer.len] = FORMAT;
|
|
248
|
+
schemaBuffer.len += 1;
|
|
249
|
+
schemaBuffer.buf[schemaBuffer.len] = stringFormats.indexOf(obj.format);
|
|
250
|
+
schemaBuffer.len += 1;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
if (key === 'types') {
|
|
255
|
+
ensureCapacity(1);
|
|
256
|
+
schemaBuffer.buf[schemaBuffer.len] = TYPES;
|
|
257
|
+
schemaBuffer.len += 1;
|
|
258
|
+
}
|
|
259
|
+
else if (key === 'props') {
|
|
260
|
+
ensureCapacity(1);
|
|
261
|
+
schemaBuffer.buf[schemaBuffer.len] = PROPS;
|
|
262
|
+
schemaBuffer.len += 1;
|
|
57
263
|
}
|
|
58
264
|
else {
|
|
59
|
-
|
|
60
|
-
walk(val, obj, prev, true, schemaBuffer);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
walk(val, obj, prev, fromObject, schemaBuffer);
|
|
64
|
-
}
|
|
265
|
+
encodeKey(key, schemaBuffer);
|
|
65
266
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// derp
|
|
69
|
-
}
|
|
70
|
-
else if (type === 'number') {
|
|
71
|
-
// do stuff
|
|
267
|
+
// important to handle the size here...
|
|
268
|
+
handleSingleValue(opts, obj[key], obj, prev, fromObject, key);
|
|
72
269
|
}
|
|
73
270
|
}
|
|
74
271
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
272
|
+
let size = schemaBuffer.len - start;
|
|
273
|
+
// 3
|
|
274
|
+
// if (size < 252) {
|
|
275
|
+
// console.log('FLAP>', size)
|
|
276
|
+
// schemaBuffer.buf[sizeIndex] = size + 3
|
|
277
|
+
// schemaBuffer.buf.set(
|
|
278
|
+
// schemaBuffer.buf.subarray(sizeIndex + 4, sizeIndex + size),
|
|
279
|
+
// sizeIndex + 1,
|
|
280
|
+
// )
|
|
281
|
+
// schemaBuffer.len -= 4
|
|
282
|
+
// } else {
|
|
283
|
+
schemaBuffer.buf[sizeIndex] = 0; // means 4
|
|
284
|
+
writeUint32(schemaBuffer.buf, size, sizeIndex + 1);
|
|
285
|
+
// }
|
|
78
286
|
};
|
|
79
|
-
export const serialize = (schema,
|
|
80
|
-
// schema: StrictSchema,
|
|
81
|
-
noCompression = false) => {
|
|
287
|
+
export const serialize = (schema, opts = {}) => {
|
|
82
288
|
if (!schemaBuffer) {
|
|
83
|
-
// 1mb buffer add check if its large enough else increase
|
|
84
289
|
schemaBuffer = {
|
|
85
|
-
buf: new Uint8Array(
|
|
290
|
+
buf: new Uint8Array(10e3), // 10kb default
|
|
86
291
|
len: 0,
|
|
87
292
|
dictMap: {},
|
|
88
293
|
};
|
|
89
294
|
}
|
|
90
|
-
schemaBuffer.dictMap = {};
|
|
91
295
|
schemaBuffer.len = 0;
|
|
92
|
-
|
|
93
|
-
|
|
296
|
+
schemaBuffer.dictMap = {};
|
|
297
|
+
// defalte not supported in unpacking yet
|
|
298
|
+
const isDeflate = 0; // opts.deflate ? 1 : 0
|
|
299
|
+
walk(opts, schema, undefined, undefined, false, schemaBuffer);
|
|
94
300
|
const packed = new Uint8Array(schemaBuffer.buf.subarray(0, schemaBuffer.len));
|
|
95
|
-
if (isDeflate) {
|
|
96
|
-
|
|
301
|
+
// if (isDeflate) {
|
|
302
|
+
// // add extra byte! see if nessecary
|
|
303
|
+
// return deflate.deflateSync(packed)
|
|
304
|
+
// } else {
|
|
305
|
+
return packed;
|
|
306
|
+
// }
|
|
307
|
+
};
|
|
308
|
+
const decoder = new TextDecoder();
|
|
309
|
+
export const deSerializeKey = (buf, keySize, i) => {
|
|
310
|
+
let size = 0;
|
|
311
|
+
let value;
|
|
312
|
+
if (keySize === KEY_ADDRESS_3_BYTES) {
|
|
313
|
+
const dictAddress = readUint24(buf, i);
|
|
314
|
+
size += 3;
|
|
315
|
+
const actualKeySize = buf[dictAddress] - KEY_OPTS;
|
|
316
|
+
value = decoder.decode(buf.subarray(dictAddress + 1, actualKeySize + dictAddress + 1));
|
|
317
|
+
}
|
|
318
|
+
else if (keySize === KEY_ADDRESS_2_BYTES) {
|
|
319
|
+
const dictAddress = readUint16(buf, i);
|
|
320
|
+
size += 2;
|
|
321
|
+
const actualKeySize = buf[dictAddress] - KEY_OPTS;
|
|
322
|
+
value = decoder.decode(buf.subarray(dictAddress + 1, actualKeySize + dictAddress + 1));
|
|
323
|
+
}
|
|
324
|
+
else if (keySize === KEY_ADDRESS_1_BYTE) {
|
|
325
|
+
const dictAddress = buf[i];
|
|
326
|
+
size += 1;
|
|
327
|
+
const actualKeySize = buf[dictAddress] - KEY_OPTS;
|
|
328
|
+
value = decoder.decode(buf.subarray(dictAddress + 1, actualKeySize + dictAddress + 1));
|
|
97
329
|
}
|
|
98
330
|
else {
|
|
99
|
-
|
|
331
|
+
const actualKeySize = keySize - KEY_OPTS;
|
|
332
|
+
value = decoder.decode(buf.subarray(i, actualKeySize + i));
|
|
333
|
+
size += actualKeySize;
|
|
100
334
|
}
|
|
335
|
+
return { size, value };
|
|
101
336
|
};
|
|
102
|
-
const
|
|
103
|
-
export const deSerializeInner = (buf, obj, start) => {
|
|
337
|
+
export const deSerializeInner = (buf, obj, start, fromArray) => {
|
|
104
338
|
let i = start;
|
|
105
|
-
const isSchemaProp = buf[i] ===
|
|
339
|
+
const isSchemaProp = buf[i] === SCHEMA_PROP;
|
|
106
340
|
i += 1;
|
|
107
341
|
if (isSchemaProp) {
|
|
108
342
|
const type = buf[i];
|
|
109
343
|
const parsedType = REVERSE_TYPE_INDEX_MAP[type];
|
|
110
|
-
|
|
344
|
+
if (type !== ENUM) {
|
|
345
|
+
obj.type = parsedType;
|
|
346
|
+
}
|
|
347
|
+
i += 1;
|
|
348
|
+
}
|
|
349
|
+
let size;
|
|
350
|
+
if (buf[i] === 0) {
|
|
351
|
+
size = readUint32(buf, i + 1);
|
|
352
|
+
i += 5;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
size = buf[i] - 3;
|
|
356
|
+
console.log('yo', size);
|
|
111
357
|
i += 1;
|
|
112
358
|
}
|
|
113
|
-
const size = buf[i] | ((buf[i + 1] << 8) >>> 0);
|
|
114
|
-
i += 2;
|
|
115
359
|
const end = size + start;
|
|
360
|
+
if (fromArray) {
|
|
361
|
+
i += 2;
|
|
362
|
+
}
|
|
116
363
|
while (i < end) {
|
|
117
|
-
let keySize = buf[i];
|
|
118
|
-
i += 1;
|
|
119
364
|
let key;
|
|
120
|
-
if (
|
|
121
|
-
|
|
365
|
+
if (fromArray) {
|
|
366
|
+
if (obj.length < 256) {
|
|
367
|
+
key = buf[i];
|
|
368
|
+
i += 1;
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
key = readUint16(buf, i);
|
|
372
|
+
i += 2;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
let keySize = buf[i];
|
|
377
|
+
i += 1;
|
|
378
|
+
// format!
|
|
379
|
+
if (keySize === REQUIRED) {
|
|
380
|
+
obj.required = true;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
else if (keySize === FORMAT) {
|
|
384
|
+
obj.format = stringFormats[buf[i]];
|
|
385
|
+
i += 1;
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
else if (keySize === READONLY) {
|
|
389
|
+
obj.readOnly = true;
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
else if (keySize === TYPES) {
|
|
393
|
+
key = 'types';
|
|
394
|
+
}
|
|
395
|
+
else if (keySize === PROPS) {
|
|
396
|
+
key = 'props';
|
|
397
|
+
}
|
|
398
|
+
else if (keySize === REF) {
|
|
399
|
+
const valueKeySize = buf[i];
|
|
400
|
+
i += 1;
|
|
401
|
+
const { size, value } = deSerializeKey(buf, valueKeySize, i);
|
|
402
|
+
i += size;
|
|
403
|
+
obj.ref = value;
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
else if (keySize === PROP) {
|
|
407
|
+
const valueKeySize = buf[i];
|
|
408
|
+
i += 1;
|
|
409
|
+
const { size, value } = deSerializeKey(buf, valueKeySize, i);
|
|
410
|
+
i += size;
|
|
411
|
+
obj.prop = value;
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
const { size, value } = deSerializeKey(buf, keySize, i);
|
|
416
|
+
i += size;
|
|
417
|
+
key = value;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (buf[i] === UINT8) {
|
|
421
|
+
i += 1;
|
|
422
|
+
obj[key] = buf[i];
|
|
423
|
+
i += 1;
|
|
424
|
+
}
|
|
425
|
+
else if (buf[i] === FALSE) {
|
|
426
|
+
i += 1;
|
|
427
|
+
obj[key] = false;
|
|
428
|
+
}
|
|
429
|
+
else if (buf[i] === TRUE) {
|
|
430
|
+
i += 1;
|
|
431
|
+
obj[key] = true;
|
|
432
|
+
}
|
|
433
|
+
else if (buf[i] === FUNCTION) {
|
|
434
|
+
i += 1;
|
|
435
|
+
const size = readUint16(buf, i);
|
|
122
436
|
i += 2;
|
|
123
|
-
|
|
124
|
-
key =
|
|
437
|
+
const fn = `return (${decoder.decode(buf.subarray(i, i + size))})(payload, prop)`;
|
|
438
|
+
obj[key] = new Function('payload', 'prop', fn);
|
|
439
|
+
i += size;
|
|
440
|
+
}
|
|
441
|
+
else if (buf[i] === STRING) {
|
|
442
|
+
i += 1;
|
|
443
|
+
const size = readUint16(buf, i);
|
|
444
|
+
i += 2;
|
|
445
|
+
obj[key] = decoder.decode(buf.subarray(i, i + size));
|
|
446
|
+
i += size;
|
|
447
|
+
}
|
|
448
|
+
else if (buf[i] === BINARY) {
|
|
449
|
+
i += 1;
|
|
450
|
+
const size = readUint16(buf, i);
|
|
451
|
+
i += 2;
|
|
452
|
+
obj[key] = buf.subarray(i, size + i);
|
|
453
|
+
i += size;
|
|
454
|
+
}
|
|
455
|
+
else if (buf[i] === UINT32) {
|
|
456
|
+
obj[key] = readUint32(buf, i + 1);
|
|
457
|
+
i += 5;
|
|
458
|
+
}
|
|
459
|
+
else if (buf[i] === FLOAT64) {
|
|
460
|
+
obj[key] = readDoubleLE(buf, i + 1);
|
|
461
|
+
i += 9;
|
|
462
|
+
}
|
|
463
|
+
else if (buf[i] === OBJECT || buf[i] === SCHEMA_PROP) {
|
|
464
|
+
const nest = (obj[key] = {});
|
|
465
|
+
const fieldSize = deSerializeInner(buf, nest, i, false);
|
|
466
|
+
i += fieldSize;
|
|
467
|
+
}
|
|
468
|
+
else if (buf[i] === ARRAY) {
|
|
469
|
+
const len = readUint16(buf, i + 3);
|
|
470
|
+
const nest = (obj[key] = new Array(len));
|
|
471
|
+
const fieldSize = deSerializeInner(buf, nest, i, true);
|
|
472
|
+
i += fieldSize;
|
|
125
473
|
}
|
|
126
474
|
else {
|
|
127
|
-
|
|
128
|
-
|
|
475
|
+
console.warn('Invalid value type', buf[i], 'skip');
|
|
476
|
+
// Invalid value type
|
|
477
|
+
i += 1;
|
|
478
|
+
const size = buf[i] | ((buf[i + 1] << 8) >>> 0);
|
|
479
|
+
i += size;
|
|
129
480
|
}
|
|
130
|
-
const nest = (obj[key] = {});
|
|
131
|
-
const fieldSize = deSerializeInner(buf, nest, i);
|
|
132
|
-
i += fieldSize;
|
|
133
481
|
}
|
|
134
482
|
return i - start;
|
|
135
483
|
};
|
|
136
484
|
export const deSerialize = (buf) => {
|
|
137
485
|
// if first byte is deflate
|
|
138
486
|
const schema = {};
|
|
139
|
-
deSerializeInner(buf, schema, 0);
|
|
487
|
+
deSerializeInner(buf, schema, 0, false);
|
|
140
488
|
return schema;
|
|
141
489
|
};
|
|
142
490
|
//# sourceMappingURL=serialize.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -96,6 +96,11 @@ export type SchemaVector = Prop<{
|
|
|
96
96
|
default?: Float32Array;
|
|
97
97
|
size: number;
|
|
98
98
|
}>;
|
|
99
|
+
export type SchemaColvec = Prop<{
|
|
100
|
+
type: 'colvec';
|
|
101
|
+
default?: Float32Array;
|
|
102
|
+
size: number;
|
|
103
|
+
}>;
|
|
99
104
|
export type SchemaTimestamp = Prop<{
|
|
100
105
|
type: 'timestamp';
|
|
101
106
|
default?: number | Date | string;
|
|
@@ -150,7 +155,7 @@ export type SchemaSet<ItemsType extends SetItems = SetItems> = Prop<{
|
|
|
150
155
|
} ? ItemsType['default'][] : undefined;
|
|
151
156
|
items: ItemsType & NeverInItems;
|
|
152
157
|
}>;
|
|
153
|
-
type NonRefSchemaProps<isStrict = false> = SchemaTimestamp | SchemaBoolean | SchemaNumber | SchemaString | SchemaAlias | SchemaText | SchemaEnum | SchemaJson | SchemaBinary | SchemaCardinality | SchemaVector | (isStrict extends true ? SchemaSet<SetItems<true>> : SchemaPropShorthand | SchemaSet);
|
|
158
|
+
type NonRefSchemaProps<isStrict = false> = SchemaTimestamp | SchemaBoolean | SchemaNumber | SchemaString | SchemaAlias | SchemaText | SchemaEnum | SchemaJson | SchemaBinary | SchemaCardinality | SchemaVector | SchemaColvec | (isStrict extends true ? SchemaSet<SetItems<true>> : SchemaPropShorthand | SchemaSet);
|
|
154
159
|
export type SchemaProp<isStrict = false> = SchemaReferencesWithQuery | SchemaReferenceWithQuery | NonRefSchemaProps<isStrict> | SchemaReferences | SchemaReference | SchemaObject | SchemaBinary;
|
|
155
160
|
export type SchemaPropOneWay<isStrict = false> = SchemaReferencesOneWay | SchemaReferenceOneWay | SchemaObjectOneWay | NonRefSchemaProps<isStrict>;
|
|
156
161
|
export type SchemaAnyProp = SchemaPropOneWay | SchemaProp;
|
|
@@ -165,6 +170,9 @@ type GenericSchemaType<isStrict = false> = {
|
|
|
165
170
|
delete?: SchemaHook;
|
|
166
171
|
};
|
|
167
172
|
id?: number;
|
|
173
|
+
blockCapacity?: number;
|
|
174
|
+
insertOnly?: boolean;
|
|
175
|
+
partial?: boolean;
|
|
168
176
|
props: SchemaProps<isStrict>;
|
|
169
177
|
};
|
|
170
178
|
export type StrictSchemaType = GenericSchemaType<true>;
|
|
@@ -204,6 +212,7 @@ export type SchemaPropTypeMap = {
|
|
|
204
212
|
binary: SchemaBinary;
|
|
205
213
|
cardinality: SchemaCardinality;
|
|
206
214
|
vector: SchemaVector;
|
|
215
|
+
colvec: SchemaColvec;
|
|
207
216
|
} & Record<NumberType, SchemaNumber>;
|
|
208
217
|
export type SchemaPropTypes = keyof SchemaPropTypeMap;
|
|
209
218
|
export declare const isPropType: <T extends SchemaPropTypes>(type: T, prop: SchemaProp) => prop is SchemaPropTypeMap[T];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@based/schema",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.22",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
"typescript": "^5.6.3"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"
|
|
33
|
-
"@saulx/utils": "^6.7.0",
|
|
32
|
+
"@saulx/utils": "^6.7.2",
|
|
34
33
|
"picocolors": "^1.1.0"
|
|
35
34
|
}
|
|
36
35
|
}
|