@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.
@@ -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
  };
@@ -3,6 +3,8 @@ export const createEmptyDef = (typeName, type, locales) => {
3
3
  return {
4
4
  cnt: 0,
5
5
  blockCapacity: 0,
6
+ insertOnly: false,
7
+ partial: false,
6
8
  checksum: hashObjectIgnoreKeyOrder(type),
7
9
  type: typeName,
8
10
  props: {},
@@ -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
@@ -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);
@@ -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;
@@ -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 field in schemaTypesParsed) {
17
- if (field in schema.types) {
15
+ for (const typeName in schemaTypesParsed) {
16
+ if (typeName in schema.types) {
18
17
  continue;
19
18
  }
20
- const id = schemaTypesParsed[field].id;
21
- delete schemaTypesParsed[field];
19
+ const id = schemaTypesParsed[typeName].id;
20
+ delete schemaTypesParsed[typeName];
22
21
  delete schemaTypesParsedById[id];
23
22
  }
24
- for (const field in schema.types) {
25
- const type = schema.types[field];
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(field, type, schemaTypesParsed, schema.locales ?? {
28
+ const def = createSchemaTypeDef(typeName, type, schemaTypesParsed, schema.locales ?? {
30
29
  en: {},
31
30
  });
32
- def.blockCapacity = field === '_root' ? 2147483647 : DEFAULT_BLOCK_CAPACITY;
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 (result.id == 0 && top) {
40
- if ('id' in type) {
41
- result.id = type.id;
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
- else {
44
- throw new Error(`Invalid schema type id ${result.type}`);
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) {
@@ -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) => {
@@ -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);
@@ -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)) {
@@ -1,5 +1,14 @@
1
1
  import { StrictSchema } from './types.js';
2
- export declare const serialize: (schema: any, noCompression?: boolean) => Uint8Array;
3
- export declare const deSerializeInner: (buf: Uint8Array, obj: any, start: number) => number;
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 { REVERSE_TYPE_INDEX_MAP, TYPE_INDEX_MAP } from './def/types.js';
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
- // HANDLE ENUM
12
- const isSchemaProp = 'type' in obj && (prev2?.type === 'object' || fromObject === false);
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++] = 254;
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++] = 255;
173
+ schemaBuffer.buf[schemaBuffer.len++] = isArray ? ARRAY : OBJECT;
20
174
  }
21
175
  let sizeIndex = schemaBuffer.len;
22
- schemaBuffer.len += 2;
23
- for (const key in obj) {
24
- if (key === 'type' && isSchemaProp) {
25
- continue;
26
- }
27
- else {
28
- let address = schemaBuffer.dictMap[key];
29
- // if len == 1 never from address
30
- if (!address) {
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[schemaBuffer.len] = 0;
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
- const val = obj[key];
46
- const type = typeof val;
47
- // typed Array
48
- if (Array.isArray(val)) {
49
- // derp
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 (type === 'function') {
52
- // derp
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 (type === 'object') {
55
- // fromObject
56
- if (val === null) {
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
- if (!fromObject && key === 'props' && obj.type === 'object') {
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
- else if (type === 'string') {
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
- const size = schemaBuffer.len - start;
76
- schemaBuffer.buf[sizeIndex] = size;
77
- schemaBuffer.buf[sizeIndex + 1] = size >>> 8;
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(1e6),
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
- const isDeflate = noCompression ? 0 : 1;
93
- walk(schema, undefined, undefined, false, schemaBuffer);
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
- return deflate.deflateSync(packed);
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
- return packed;
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 decoder = new TextDecoder();
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] === 254;
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
- obj.type = parsedType;
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 (keySize === 0) {
121
- const dictAddress = buf[i] | ((buf[i + 1] << 8) >>> 0);
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
- keySize = buf[dictAddress];
124
- key = decoder.decode(buf.subarray(dictAddress + 1, keySize + dictAddress + 1));
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
- key = decoder.decode(buf.subarray(i, keySize + i));
128
- i += keySize;
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.20",
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
- "fflate": "0.8.1",
33
- "@saulx/utils": "^6.7.0",
32
+ "@saulx/utils": "^6.7.2",
34
33
  "picocolors": "^1.1.0"
35
34
  }
36
35
  }