@based/schema 5.0.0-alpha.2 → 5.0.0-alpha.20

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.
@@ -0,0 +1,4 @@
1
+ import { SchemaReference } from '../index.js';
2
+ import { PropDef } from './types.js';
3
+ export declare const addEdges: (prop: PropDef, refProp: SchemaReference) => void;
4
+ //# sourceMappingURL=addEdges.d.ts.map
@@ -0,0 +1,76 @@
1
+ import { getPropType } from '../index.js';
2
+ import { DEFAULT_MAP } from './defaultMap.js';
3
+ import { TYPE_INDEX_MAP, REFERENCES, REFERENCE, ENUM, NUMBER, } from './types.js';
4
+ import { getPropLen, isSeparate, parseMinMaxStep } from './utils.js';
5
+ import { defaultValidation, VALIDATION_MAP } from './validation.js';
6
+ export const addEdges = (prop, refProp) => {
7
+ for (const key in refProp) {
8
+ if (key[0] === '$') {
9
+ if (!prop.edges) {
10
+ prop.edgeMainLen = 0;
11
+ prop.edges = {};
12
+ prop.reverseSeperateEdges = {};
13
+ prop.reverseMainEdges = {};
14
+ prop.edgesSeperateCnt = 0;
15
+ }
16
+ const edgeProp = refProp[key];
17
+ const edgeType = getPropType(edgeProp);
18
+ const len = getPropLen(edgeProp);
19
+ const separate = isSeparate(edgeProp, len);
20
+ if (separate) {
21
+ prop.edgesSeperateCnt++;
22
+ }
23
+ const typeIndex = TYPE_INDEX_MAP[edgeType];
24
+ // add default
25
+ const edge = {
26
+ __isPropDef: true,
27
+ __isEdge: true,
28
+ prop: separate ? prop.edgesSeperateCnt : 0,
29
+ validation: edgeProp.validation ?? VALIDATION_MAP[typeIndex] ?? defaultValidation,
30
+ name: key,
31
+ typeIndex,
32
+ len,
33
+ separate,
34
+ path: [...prop.path, key],
35
+ default: edgeProp.default ?? DEFAULT_MAP[typeIndex],
36
+ start: prop.edgeMainLen,
37
+ };
38
+ if (edgeProp.max !== undefined) {
39
+ edge.max = parseMinMaxStep(edgeProp.max);
40
+ }
41
+ if (edgeProp.min !== undefined) {
42
+ edge.min = parseMinMaxStep(edgeProp.min);
43
+ }
44
+ if (edgeProp.step !== undefined) {
45
+ edge.step = parseMinMaxStep(edgeProp.step);
46
+ }
47
+ if (edge.typeIndex !== NUMBER && edge.step === undefined) {
48
+ edge.step = 1;
49
+ }
50
+ prop.edgeMainLen += edge.len;
51
+ if (edge.typeIndex === ENUM) {
52
+ edge.enum = Array.isArray(refProp[key])
53
+ ? refProp[key]
54
+ : refProp[key].enum;
55
+ edge.reverseEnum = {};
56
+ for (let i = 0; i < edge.enum.length; i++) {
57
+ edge.reverseEnum[edge.enum[i]] = i;
58
+ }
59
+ }
60
+ else if (edge.typeIndex === REFERENCES) {
61
+ edge.inverseTypeName = refProp[key].items.ref;
62
+ }
63
+ else if (edge.typeIndex === REFERENCE) {
64
+ edge.inverseTypeName = refProp[key].ref;
65
+ }
66
+ prop.edges[key] = edge;
67
+ if (separate) {
68
+ prop.reverseSeperateEdges[edge.prop] = edge;
69
+ }
70
+ else {
71
+ prop.reverseMainEdges[edge.start] = edge;
72
+ }
73
+ }
74
+ }
75
+ };
76
+ //# sourceMappingURL=addEdges.js.map
@@ -0,0 +1,40 @@
1
+ import { SchemaLocales, SchemaObject, StrictSchemaType } from '../types.js';
2
+ export declare const createEmptyDef: (typeName: string, type: StrictSchemaType | SchemaObject, locales: Partial<SchemaLocales>) => {
3
+ cnt: number;
4
+ blockCapacity: number;
5
+ checksum: number;
6
+ type: string;
7
+ props: {};
8
+ reverseProps: {};
9
+ idUint8: Uint8Array;
10
+ id: number;
11
+ mainEmpty: Uint8Array;
12
+ mainLen: number;
13
+ separate: any[];
14
+ tree: {};
15
+ total: number;
16
+ lastId: number;
17
+ locales: {};
18
+ main: {};
19
+ separateSortProps: number;
20
+ separateSortText: number;
21
+ localeSize: number;
22
+ hasSeperateSort: boolean;
23
+ seperateSort: {
24
+ size: number;
25
+ props: any[];
26
+ buffer: Uint8Array;
27
+ bufferTmp: Uint8Array;
28
+ };
29
+ hasSeperateTextSort: boolean;
30
+ seperateTextSort: {
31
+ size: number;
32
+ props: any[];
33
+ buffer: Uint8Array;
34
+ noUndefined: Uint8Array;
35
+ bufferTmp: Uint8Array;
36
+ localeStringToIndex: Map<any, any>;
37
+ localeToIndex: Map<any, any>;
38
+ };
39
+ };
40
+ //# sourceMappingURL=createEmptyDef.d.ts.map
@@ -0,0 +1,43 @@
1
+ import { hashObjectIgnoreKeyOrder } from '@saulx/hash';
2
+ export const createEmptyDef = (typeName, type, locales) => {
3
+ return {
4
+ cnt: 0,
5
+ blockCapacity: 0,
6
+ checksum: hashObjectIgnoreKeyOrder(type),
7
+ type: typeName,
8
+ props: {},
9
+ reverseProps: {},
10
+ idUint8: new Uint8Array([0, 0]),
11
+ // empty main buffer
12
+ id: 0,
13
+ mainEmpty: new Uint8Array(0),
14
+ mainLen: 0,
15
+ separate: [],
16
+ tree: {},
17
+ total: 0,
18
+ lastId: 0,
19
+ locales: {},
20
+ main: {},
21
+ separateSortProps: 0,
22
+ separateSortText: 0,
23
+ localeSize: 0,
24
+ hasSeperateSort: false,
25
+ seperateSort: {
26
+ size: 0,
27
+ props: [],
28
+ buffer: new Uint8Array([]),
29
+ bufferTmp: new Uint8Array([]),
30
+ },
31
+ hasSeperateTextSort: false,
32
+ seperateTextSort: {
33
+ size: 0, // prop len
34
+ props: [],
35
+ buffer: new Uint8Array([]),
36
+ noUndefined: new Uint8Array(new Array(Object.keys(locales).length).fill(0)),
37
+ bufferTmp: new Uint8Array([]),
38
+ localeStringToIndex: new Map(),
39
+ localeToIndex: new Map(),
40
+ },
41
+ };
42
+ };
43
+ //# sourceMappingURL=createEmptyDef.js.map
@@ -0,0 +1,3 @@
1
+ import { TypeIndex } from './types.js';
2
+ export declare const DEFAULT_MAP: Record<TypeIndex, any>;
3
+ //# sourceMappingURL=defaultMap.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { TYPE_INDEX_MAP } from './types.js';
2
+ // TODO update defaults
3
+ export const DEFAULT_MAP = {
4
+ [TYPE_INDEX_MAP.alias]: '',
5
+ [TYPE_INDEX_MAP.binary]: new Uint8Array([]),
6
+ [TYPE_INDEX_MAP.boolean]: false,
7
+ [TYPE_INDEX_MAP.cardinality]: 0,
8
+ [TYPE_INDEX_MAP.number]: 0,
9
+ [TYPE_INDEX_MAP.timestamp]: 0,
10
+ [TYPE_INDEX_MAP.enum]: 0,
11
+ [TYPE_INDEX_MAP.id]: 0,
12
+ [TYPE_INDEX_MAP.int16]: 0,
13
+ [TYPE_INDEX_MAP.int32]: 0,
14
+ [TYPE_INDEX_MAP.int8]: 0,
15
+ [TYPE_INDEX_MAP.uint8]: 0,
16
+ [TYPE_INDEX_MAP.uint16]: 0,
17
+ [TYPE_INDEX_MAP.uint32]: 0,
18
+ [TYPE_INDEX_MAP.json]: null,
19
+ [TYPE_INDEX_MAP.microbuffer]: undefined,
20
+ [TYPE_INDEX_MAP.reference]: undefined,
21
+ [TYPE_INDEX_MAP.references]: [],
22
+ [TYPE_INDEX_MAP.string]: '',
23
+ [TYPE_INDEX_MAP.aliases]: [],
24
+ [TYPE_INDEX_MAP.text]: {},
25
+ [TYPE_INDEX_MAP.vector]: undefined, // maybe not can set a vec with 0
26
+ };
27
+ //# sourceMappingURL=defaultMap.js.map
@@ -0,0 +1,5 @@
1
+ import { PropDef } from './types.js';
2
+ export declare const ENCODER: TextEncoder;
3
+ export declare const fillEmptyMain: (vals: PropDef[], mainLen: number) => Uint8Array;
4
+ export declare const isZeroes: (buf: Uint8Array) => boolean;
5
+ //# sourceMappingURL=fillEmptyMain.d.ts.map
@@ -0,0 +1,61 @@
1
+ import { convertToTimestamp } from '@saulx/utils';
2
+ import { BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TIMESTAMP, UINT16, UINT32, UINT8, } from './types.js';
3
+ // Lets add validation of values in here - need to validate DEFAULT!
4
+ export const ENCODER = new TextEncoder();
5
+ export const fillEmptyMain = (vals, mainLen) => {
6
+ const mainEmpty = new Uint8Array(mainLen);
7
+ for (const f of vals) {
8
+ if (f.separate) {
9
+ continue;
10
+ }
11
+ const t = f.typeIndex;
12
+ const s = f.start;
13
+ let val = f.default;
14
+ if (t === ENUM) {
15
+ mainEmpty[s] =
16
+ typeof f.default === 'number' ? f.default : f.reverseEnum[val];
17
+ }
18
+ else if (t === INT8 || t === UINT8) {
19
+ mainEmpty[s] = val;
20
+ }
21
+ else if (t === BOOLEAN) {
22
+ mainEmpty[s] = val === true ? 1 : 0;
23
+ }
24
+ else if (t === UINT32 || t === INT32) {
25
+ mainEmpty[s] = val;
26
+ mainEmpty[s + 1] = val >>>= 8;
27
+ mainEmpty[s + 2] = val >>>= 8;
28
+ mainEmpty[s + 3] = val >>>= 8;
29
+ }
30
+ else if (t === UINT16 || t === INT16) {
31
+ mainEmpty[s] = val;
32
+ mainEmpty[s + 1] = val >>>= 8;
33
+ }
34
+ else if (t === NUMBER || t === TIMESTAMP) {
35
+ const view = new DataView(mainEmpty.buffer, s, 8);
36
+ view.setFloat64(0, convertToTimestamp(val), true);
37
+ }
38
+ else if (t === STRING) {
39
+ val = ENCODER.encode(val);
40
+ mainEmpty[s] = val.byteLength;
41
+ mainEmpty.set(val, s + 1);
42
+ }
43
+ else if (t === BINARY) {
44
+ if (val !== undefined) {
45
+ mainEmpty.set(val, s);
46
+ }
47
+ }
48
+ }
49
+ return mainEmpty;
50
+ };
51
+ export const isZeroes = (buf) => {
52
+ let i = 0;
53
+ while (i < buf.byteLength) {
54
+ if (buf[i] !== 0) {
55
+ return false;
56
+ }
57
+ i++;
58
+ }
59
+ return true;
60
+ };
61
+ //# sourceMappingURL=fillEmptyMain.js.map
@@ -0,0 +1,8 @@
1
+ export * from './types.js';
2
+ export * from './typeDef.js';
3
+ export * from './utils.js';
4
+ export * from './selvaBuffer.js';
5
+ export * from './createEmptyDef.js';
6
+ export * from './defaultMap.js';
7
+ export * from './validation.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,9 @@
1
+ // flap
2
+ export * from './types.js';
3
+ export * from './typeDef.js';
4
+ export * from './utils.js';
5
+ export * from './selvaBuffer.js';
6
+ export * from './createEmptyDef.js';
7
+ export * from './defaultMap.js';
8
+ export * from './validation.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ import { SchemaTypeDef } from './types.js';
2
+ export declare function makeSeparateSort(result: Partial<SchemaTypeDef>): void;
3
+ //# sourceMappingURL=makeSeparateSort.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { STRING, ALIAS, CARDINALITY } from './types.js';
2
+ export function makeSeparateSort(result) {
3
+ result.hasSeperateSort = true;
4
+ let max = 0;
5
+ for (const f of result.separate) {
6
+ if (f.typeIndex === STRING ||
7
+ f.typeIndex === ALIAS ||
8
+ f.typeIndex === CARDINALITY) {
9
+ if (f.prop > max) {
10
+ max = f.prop;
11
+ }
12
+ }
13
+ }
14
+ result.seperateSort.buffer = new Uint8Array(max + 1);
15
+ for (const f of result.separate) {
16
+ if (f.typeIndex === STRING ||
17
+ f.typeIndex === ALIAS ||
18
+ f.typeIndex === CARDINALITY) {
19
+ result.seperateSort.buffer[f.prop] = 1;
20
+ result.seperateSort.props.push(f);
21
+ result.seperateSort.size++;
22
+ }
23
+ }
24
+ result.seperateSort.bufferTmp = new Uint8Array(max + 1);
25
+ result.seperateSort.buffer.set(result.seperateSort.bufferTmp);
26
+ }
27
+ //# sourceMappingURL=makeSeparateSort.js.map
@@ -0,0 +1,3 @@
1
+ import { SchemaTypeDef } from './types.js';
2
+ export declare function makeSeparateTextSort(result: Partial<SchemaTypeDef>): void;
3
+ //# sourceMappingURL=makeSeparateTextSort.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { langCodesMap } from '../lang.js';
2
+ import { TEXT } from './types.js';
3
+ export function makeSeparateTextSort(result) {
4
+ result.hasSeperateTextSort = true;
5
+ let max = 0;
6
+ for (const f of result.separate) {
7
+ if (f.typeIndex === TEXT) {
8
+ if (f.prop > max) {
9
+ max = f.prop;
10
+ }
11
+ }
12
+ }
13
+ const bufLen = (max + 1) * (result.localeSize + 1);
14
+ result.seperateTextSort.buffer = new Uint8Array(bufLen);
15
+ let index = 0;
16
+ for (const code in result.locales) {
17
+ const codeLang = langCodesMap.get(code);
18
+ result.seperateTextSort.localeStringToIndex.set(code, new Uint8Array([index + 1, codeLang]));
19
+ result.seperateTextSort.localeToIndex.set(codeLang, index + 1);
20
+ index++;
21
+ }
22
+ for (const f of result.separate) {
23
+ if (f.typeIndex === TEXT) {
24
+ const index = f.prop * (result.localeSize + 1);
25
+ result.seperateTextSort.buffer[index] = result.localeSize;
26
+ for (const [, locales] of result.seperateTextSort.localeStringToIndex) {
27
+ result.seperateTextSort.buffer[locales[0] + index] = locales[1];
28
+ }
29
+ result.seperateTextSort.props.push(f);
30
+ result.seperateTextSort.size += result.localeSize;
31
+ }
32
+ }
33
+ result.seperateTextSort.props.sort((a, b) => (a.prop > b.prop ? 1 : -1));
34
+ result.seperateTextSort.bufferTmp = new Uint8Array(bufLen);
35
+ result.seperateTextSort.bufferTmp.fill(0);
36
+ result.seperateTextSort.bufferTmp.set(result.seperateTextSort.buffer);
37
+ }
38
+ //# sourceMappingURL=makeSeparateTextSort.js.map
@@ -0,0 +1,5 @@
1
+ import { SchemaTypeDef } from './types.js';
2
+ export declare function schemaToSelvaBuffer(schema: {
3
+ [key: string]: SchemaTypeDef;
4
+ }): ArrayBuffer[];
5
+ //# sourceMappingURL=selvaBuffer.d.ts.map
@@ -0,0 +1,136 @@
1
+ import { ALIAS, ALIASES, BINARY, EMPTY_MICRO_BUFFER, CARDINALITY, MICRO_BUFFER, REFERENCE, REFERENCES, STRING, TEXT, VECTOR, WEAK_REFERENCE, WEAK_REFERENCES, JSON, } from './types.js';
2
+ const selvaFieldType = {
3
+ NULL: 0,
4
+ MICRO_BUFFER: 1,
5
+ STRING: 2,
6
+ TEXT: 3,
7
+ REFERENCE: 4,
8
+ REFERENCES: 5,
9
+ WEAK_REFERENCE: 6,
10
+ WEAK_REFERENCES: 7,
11
+ ALIAS: 8,
12
+ ALIASES: 9,
13
+ COLVEC: 10,
14
+ };
15
+ const selvaTypeMap = new Uint8Array(32); // 1.2x faster than JS array
16
+ selvaTypeMap[MICRO_BUFFER] = selvaFieldType.MICRO_BUFFER;
17
+ selvaTypeMap[VECTOR] = selvaFieldType.MICRO_BUFFER;
18
+ selvaTypeMap[BINARY] = selvaFieldType.STRING;
19
+ selvaTypeMap[CARDINALITY] = selvaFieldType.STRING;
20
+ selvaTypeMap[JSON] = selvaFieldType.STRING;
21
+ selvaTypeMap[STRING] = selvaFieldType.STRING;
22
+ selvaTypeMap[TEXT] = selvaFieldType.TEXT;
23
+ selvaTypeMap[REFERENCE] = selvaFieldType.REFERENCE;
24
+ selvaTypeMap[REFERENCES] = selvaFieldType.REFERENCES;
25
+ selvaTypeMap[WEAK_REFERENCE] = selvaFieldType.WEAK_REFERENCE;
26
+ selvaTypeMap[WEAK_REFERENCES] = selvaFieldType.WEAK_REFERENCES;
27
+ selvaTypeMap[ALIAS] = selvaFieldType.ALIAS;
28
+ selvaTypeMap[ALIASES] = selvaFieldType.ALIASES;
29
+ const EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT = 0x01;
30
+ const EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP = 0x80;
31
+ function blockCapacity(blockCapacity) {
32
+ const buf = new Uint8Array(Uint32Array.BYTES_PER_ELEMENT);
33
+ const view = new DataView(buf.buffer);
34
+ view.setUint32(0, blockCapacity, true);
35
+ return buf;
36
+ }
37
+ function sepPropCount(props) {
38
+ return props.filter((prop) => prop.separate).length;
39
+ }
40
+ function makeEdgeConstraintFlags(prop, inverseProp) {
41
+ return ((prop.dependent ? EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT : 0x00) |
42
+ (prop.typeIndex === REFERENCE && inverseProp && inverseProp.typeIndex === REFERENCES
43
+ ? EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP
44
+ : 0x00));
45
+ }
46
+ const propDefBuffer = (schema, prop, isEdge) => {
47
+ const type = prop.typeIndex;
48
+ const selvaType = selvaTypeMap[type];
49
+ if (prop.len && (type === MICRO_BUFFER || type === VECTOR)) {
50
+ const buf = new Uint8Array(3);
51
+ const view = new DataView(buf.buffer);
52
+ buf[0] = selvaType;
53
+ view.setUint16(1, prop.len, true);
54
+ return [...buf];
55
+ }
56
+ else if (type === REFERENCE || type === REFERENCES) {
57
+ const buf = new Uint8Array(9);
58
+ const view = new DataView(buf.buffer);
59
+ const dstType = schema[prop.inverseTypeName];
60
+ let eschema = [];
61
+ // @ts-ignore
62
+ buf[0] = selvaType + 2 * !!isEdge; // field type
63
+ buf[1] = makeEdgeConstraintFlags(prop, dstType.props[prop.inversePropName]); // flags
64
+ view.setUint16(2, dstType.id, true); // dst_node_type
65
+ view.setUint32(5, 0, true); // schema_len
66
+ if (!isEdge) {
67
+ prop.inverseTypeId = dstType.id;
68
+ prop.inversePropNumber = dstType.props[prop.inversePropName].prop;
69
+ buf[4] = prop.inversePropNumber;
70
+ if (prop.edges) {
71
+ const edgesS = Object.values(prop.edges);
72
+ if (edgesS.length) {
73
+ const props = edgesS
74
+ .filter((v) => v.separate === true)
75
+ .sort((a, b) => (a.prop > b.prop ? 1 : -1));
76
+ const p = [
77
+ {
78
+ ...EMPTY_MICRO_BUFFER,
79
+ len: prop.edgeMainLen || 1, // allow zero here... else useless padding
80
+ __isEdgeDef: true,
81
+ },
82
+ // or handle this here...
83
+ ...props,
84
+ ];
85
+ eschema = p
86
+ .map((prop) => propDefBuffer(schema, prop, true))
87
+ .flat(1);
88
+ eschema.unshift(0, 0, 0, 0, sepPropCount(p), 0);
89
+ view.setUint32(5, eschema.length, true);
90
+ }
91
+ }
92
+ }
93
+ return [...buf, ...eschema];
94
+ }
95
+ else if (type === STRING ||
96
+ type === BINARY ||
97
+ type === CARDINALITY ||
98
+ type === JSON) {
99
+ return [selvaType, prop.len < 50 ? prop.len : 0];
100
+ }
101
+ {
102
+ return [selvaType];
103
+ }
104
+ };
105
+ // TODO rewrite
106
+ export function schemaToSelvaBuffer(schema) {
107
+ return Object.values(schema).map((t, i) => {
108
+ const props = Object.values(t.props);
109
+ const rest = [];
110
+ const nrFields = 1 + sepPropCount(props);
111
+ let refFields = 0;
112
+ if (nrFields >= 250) {
113
+ throw new Error('Too many fields');
114
+ }
115
+ for (const f of props) {
116
+ if (f.separate) {
117
+ if (f.typeIndex === REFERENCE || f.typeIndex === REFERENCES) {
118
+ refFields++;
119
+ }
120
+ rest.push(f);
121
+ }
122
+ }
123
+ rest.sort((a, b) => a.prop - b.prop);
124
+ return Uint8Array.from([
125
+ ...blockCapacity(t.blockCapacity),
126
+ nrFields,
127
+ 1 + refFields,
128
+ ...propDefBuffer(schema, {
129
+ ...EMPTY_MICRO_BUFFER,
130
+ len: t.mainLen === 0 ? 1 : t.mainLen,
131
+ }),
132
+ ...rest.map((f) => propDefBuffer(schema, f)).flat(1),
133
+ ]).buffer;
134
+ });
135
+ }
136
+ //# sourceMappingURL=selvaBuffer.js.map
@@ -0,0 +1,14 @@
1
+ import { SchemaObject, StrictSchemaType, SchemaLocales } from '../index.js';
2
+ import { SchemaTypeDef, SchemaTypesParsed } from './types.js';
3
+ import { StrictSchema } from '../types.js';
4
+ export declare const DEFAULT_BLOCK_CAPACITY = 100000;
5
+ export declare const updateTypeDefs: (schema: StrictSchema) => {
6
+ schemaTypesParsed: {
7
+ [key: string]: SchemaTypeDef;
8
+ };
9
+ schemaTypesParsedById: {
10
+ [id: number]: SchemaTypeDef;
11
+ };
12
+ };
13
+ export declare const createSchemaTypeDef: (typeName: string, type: StrictSchemaType | SchemaObject, parsed: SchemaTypesParsed, locales: Partial<SchemaLocales>, result?: Partial<SchemaTypeDef>, path?: string[], top?: boolean) => SchemaTypeDef;
14
+ //# sourceMappingURL=typeDef.d.ts.map