@verdant-web/common 2.3.0-next.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/esm/EventSubscriber.d.ts +18 -0
  2. package/dist/esm/baseline.d.ts +5 -0
  3. package/dist/esm/batching.d.ts +43 -0
  4. package/dist/esm/error.d.ts +22 -0
  5. package/dist/esm/files.d.ts +20 -0
  6. package/dist/esm/index.d.ts +21 -0
  7. package/dist/esm/indexes.d.ts +17 -0
  8. package/dist/esm/indexes.test.d.ts +1 -0
  9. package/dist/esm/memo.d.ts +6 -0
  10. package/dist/esm/memo.test.d.ts +1 -0
  11. package/dist/esm/migration.d.ts +174 -0
  12. package/dist/esm/oids.d.ts +95 -0
  13. package/dist/esm/oids.js +4 -4
  14. package/dist/esm/oids.js.map +1 -1
  15. package/dist/esm/oids.test.d.ts +1 -0
  16. package/dist/esm/operation.d.ts +142 -0
  17. package/dist/esm/operation.test.d.ts +1 -0
  18. package/dist/esm/patch.d.ts +28 -0
  19. package/dist/esm/presence.d.ts +29 -0
  20. package/dist/esm/protocol.d.ts +145 -0
  21. package/dist/esm/refs.d.ts +7 -0
  22. package/dist/esm/replica.d.ts +28 -0
  23. package/dist/esm/schema/children.d.ts +2 -0
  24. package/dist/esm/schema/defaults.test.d.ts +1 -0
  25. package/dist/esm/schema/fieldHelpers.d.ts +35 -0
  26. package/dist/esm/schema/fields.d.ts +10 -0
  27. package/dist/esm/schema/index.d.ts +54 -0
  28. package/dist/esm/schema/indexFilters.d.ts +6 -0
  29. package/dist/esm/schema/types/collection.d.ts +23 -0
  30. package/dist/esm/schema/types/compounds.d.ts +11 -0
  31. package/dist/esm/schema/types/fields.d.ts +55 -0
  32. package/dist/esm/schema/types/filters.d.ts +29 -0
  33. package/dist/esm/schema/types/shapes.d.ts +25 -0
  34. package/dist/esm/schema/types/synthetics.d.ts +37 -0
  35. package/dist/esm/schema/types.d.ts +18 -0
  36. package/dist/esm/schema/validation.d.ts +14 -0
  37. package/dist/esm/timestamp.d.ts +51 -0
  38. package/dist/esm/timestamp.test.d.ts +1 -0
  39. package/dist/esm/undo.d.ts +3 -0
  40. package/dist/esm/utils.d.ts +20 -0
  41. package/dist/esm/utils.test.d.ts +1 -0
  42. package/package.json +1 -1
  43. package/src/oids.ts +6 -12
@@ -0,0 +1,37 @@
1
+ import { StorageBooleanFieldSchema, StorageFieldsSchema, StorageNumberFieldSchema, StorageStringFieldSchema } from './fields.js';
2
+ import { ShapeFromFields } from './shapes.js';
3
+ export type StorageStringSyntheticSchema<Fields extends StorageFieldsSchema> = {
4
+ type: 'string';
5
+ compute: (value: ShapeFromFields<Fields>) => string | null;
6
+ };
7
+ export type StorageNumberSyntheticSchema<Fields extends StorageFieldsSchema> = {
8
+ type: 'number';
9
+ compute: (value: ShapeFromFields<Fields>) => number | null;
10
+ };
11
+ export type StorageBooleanSyntheticSchema<Fields extends StorageFieldsSchema> = {
12
+ type: 'boolean';
13
+ compute: (value: ShapeFromFields<Fields>) => boolean | null;
14
+ };
15
+ export type StorageStringArraySyntheticSchema<Fields extends StorageFieldsSchema> = {
16
+ type: 'string[]';
17
+ compute: (value: ShapeFromFields<Fields>) => string[];
18
+ };
19
+ export type StorageNumberArraySyntheticSchema<Fields extends StorageFieldsSchema> = {
20
+ type: 'number[]';
21
+ compute: (value: ShapeFromFields<Fields>) => number[];
22
+ };
23
+ export type StorageBooleanArraySyntheticSchema<Fields extends StorageFieldsSchema> = {
24
+ type: 'boolean[]';
25
+ compute: (value: ShapeFromFields<Fields>) => boolean[];
26
+ };
27
+ export type StorageDirectSyntheticSchema<Fields extends StorageFieldsSchema> = {
28
+ field: DirectIndexableFieldName<Fields>;
29
+ };
30
+ type DirectIndexableFields<Fields extends StorageFieldsSchema> = {
31
+ [K in keyof Fields as Fields[K] extends StorageStringFieldSchema ? K : Fields[K] extends StorageNumberFieldSchema ? K : Fields[K] extends StorageBooleanFieldSchema ? K : never]: any;
32
+ };
33
+ export type DirectIndexableFieldName<Fields extends StorageFieldsSchema> = keyof DirectIndexableFields<Fields> extends never ? string : keyof DirectIndexableFields<Fields>;
34
+ export type StorageSyntheticIndices<Fields extends StorageFieldsSchema> = Record<string, StorageSyntheticIndexSchema<Fields>>;
35
+ export type StorageSyntheticIndexSchema<Fields extends StorageFieldsSchema> = StorageStringSyntheticSchema<Fields> | StorageNumberSyntheticSchema<Fields> | StorageBooleanSyntheticSchema<Fields> | StorageStringArraySyntheticSchema<Fields> | StorageNumberArraySyntheticSchema<Fields> | StorageBooleanArraySyntheticSchema<Fields> | StorageDirectSyntheticSchema<Fields>;
36
+ export type IndexValueTag = Exclude<StorageSyntheticIndexSchema<any>, StorageDirectSyntheticSchema<any>>['type'];
37
+ export {};
@@ -0,0 +1,18 @@
1
+ import { StorageCollectionSchema } from './types/collection.js';
2
+ export * from './types/collection.js';
3
+ export * from './types/compounds.js';
4
+ export * from './types/fields.js';
5
+ export * from './types/filters.js';
6
+ export * from './types/shapes.js';
7
+ export * from './types/synthetics.js';
8
+ export type StorageSchema<Collections extends {
9
+ [k: string]: StorageCollectionSchema;
10
+ } = {
11
+ [k: string]: StorageCollectionSchema;
12
+ }> = {
13
+ version: number;
14
+ wip?: true;
15
+ collections: Collections;
16
+ };
17
+ export type SchemaCollectionName<Schema extends StorageSchema<any>> = Schema extends StorageSchema<infer Cs> ? Exclude<keyof Cs, number | symbol> : never;
18
+ export type SchemaCollection<Schema extends StorageSchema<any>, Name extends SchemaCollectionName<Schema>> = Schema extends StorageSchema<infer Cs> ? Cs[Name] : never;
@@ -0,0 +1,14 @@
1
+ import { StorageFieldSchema, StorageFieldsSchema } from './types.js';
2
+ export declare function validateEntity(schema: StorageFieldsSchema, entity: any): EntityValidationProblem | void;
3
+ export type EntityValidationProblem = {
4
+ type: 'null' | 'no-default' | 'invalid-type' | 'invalid-value' | 'invalid-key';
5
+ fieldPath: (string | number)[];
6
+ message: string;
7
+ };
8
+ export declare function validateEntityField({ field, value, fieldPath, depth, requireDefaults, }: {
9
+ field: StorageFieldSchema;
10
+ value: any;
11
+ fieldPath: (string | number)[];
12
+ depth?: number;
13
+ requireDefaults?: boolean;
14
+ }): EntityValidationProblem | undefined;
@@ -0,0 +1,51 @@
1
+ export interface TimestampProvider {
2
+ now(version: number): string;
3
+ update(remoteTimestamp: string): void;
4
+ zero(version: number): string;
5
+ getWallClockTime(timestamp: string): number;
6
+ }
7
+ export declare function encodeVersion(version: number | string): string;
8
+ export declare function OLD_encodeVersion(version: number | string): string;
9
+ export declare class NaiveTimestampProvider implements TimestampProvider {
10
+ counter: number;
11
+ now: (version: number | string) => string;
12
+ update: () => void;
13
+ zero: (version: number | string) => string;
14
+ getWallClockTime: (timestamp: string) => number;
15
+ }
16
+ export declare class HybridLogicalClockTimestampProvider implements TimestampProvider {
17
+ private latest;
18
+ private zeroCounter;
19
+ now: (version: string | number) => string;
20
+ /**
21
+ * @deprecated - use now() instead and update to latest format
22
+ */
23
+ OLD_now: (version: string | number) => string;
24
+ /** Get the current timer state. Does not increment counter. */
25
+ timerState: () => HLCTimestamp;
26
+ update: (remoteTimestamp: string) => void;
27
+ get: (version: string | number, raw: HLCTimestamp) => string;
28
+ zero: (version: string | number) => string;
29
+ getWallClockTime: typeof getWallClockTime;
30
+ }
31
+ interface HLCTimestamp {
32
+ time: number;
33
+ counter: number;
34
+ node: string;
35
+ }
36
+ export declare function serializeHlcTimestamp(ts: HLCTimestamp): string;
37
+ export declare function deserializeHlcTimestamp(clock: string): HLCTimestamp;
38
+ /**
39
+ * Below, converters for old-style timestamps are defined.
40
+ * These are for migrating older clients to the new format.
41
+ */
42
+ /**
43
+ * Converts a timestamp from the old format to the new format.
44
+ */
45
+ export declare function convertOldHlcTimestamp(ts: string): string;
46
+ export declare function OLD_serializeHlcTimestamp(ts: HLCTimestamp): string;
47
+ export declare function OLD_deserializeHlcTimestamp(clock: string): HLCTimestamp;
48
+ export declare function getTimestampSchemaVersion(timestamp: string): number;
49
+ export declare function compareTimestampSchemaVersions(a: string, b: string): number;
50
+ export declare function getWallClockTime(timestamp: string): number;
51
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { ObjectIdentifier } from './oids.js';
2
+ import { Operation } from './operation.js';
3
+ export declare function getUndoOperations(oid: ObjectIdentifier, initial: any, operations: Operation[], getNow: () => string): Operation[];
@@ -0,0 +1,20 @@
1
+ export declare function take<T extends object, Keys extends keyof T>(obj: T, keys: Keys[]): Pick<T, Keys>;
2
+ export declare function omit<T extends object, Keys extends keyof T>(obj: T, keys: Keys[]): Omit<T, Keys>;
3
+ export declare function getSortedIndex<T>(array: T[], insert: T, compare: (a: T, b: T) => number): number;
4
+ /**
5
+ * Consistently stringifies an object regardless
6
+ * of key insertion order
7
+ */
8
+ export declare function stableStringify(obj: any): string;
9
+ /**
10
+ * A version of structured cloning which preserves object identity
11
+ * references in the system.
12
+ */
13
+ export declare function cloneDeep<T>(obj: T, copyOids?: boolean): T;
14
+ export declare function hashObject(obj: any): string;
15
+ export declare function isObject(obj: any): any;
16
+ export declare function roughSizeOfObject(object: any): number;
17
+ export declare function assert(condition: any, message?: string): asserts condition;
18
+ export declare function generateId(length?: number): string;
19
+ export declare function findLastIndex<T>(array: T[], predicate: (item: T) => boolean): number;
20
+ export declare function debounce<T extends (...args: any[]) => any>(fn: T, wait: number): T;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdant-web/common",
3
- "version": "2.3.0-next.0",
3
+ "version": "2.3.1",
4
4
  "access": "public",
5
5
  "type": "module",
6
6
  "exports": {
package/src/oids.ts CHANGED
@@ -12,22 +12,16 @@ import { isObject, assert } from './utils.js';
12
12
  * on its own and associating it back to its parent.
13
13
  *
14
14
  * An OID is structured as such:
15
- * <collection>/<root id>[/<key paths>]:<random>
15
+ * <collection>/<root id>:<random>
16
16
  *
17
17
  * OIDs have a few characteristics:
18
18
  * - They include the collection name of the parent document
19
19
  * - They include the primary key of the parent document
20
- * - They include the key path of the object within the document
21
- * - They include a random sequence to identify different objects which
22
- * exist at the same key path
20
+ * - They may include a random sequence to identify sub-objects
23
21
  *
24
22
  * Collection name and document key are used to link any isolated
25
23
  * object back to its parent document.
26
24
  *
27
- * The key path is used for authorization - to associate the object
28
- * (or an operation related to it by OID) with the field it inhabits
29
- * to utilize authorization rules from that field in the schema.
30
- *
31
25
  * The random sequence allows the application to encode different
32
26
  * identities for objects at the same position in a document for
33
27
  * conflict resolution purposes
@@ -127,7 +121,7 @@ export function ensureCompatibleOid(
127
121
  }
128
122
  }
129
123
 
130
- const SANTIIZE_PLACEHOLDERS = {
124
+ const SANITIZE_PLACEHOLDERS = {
131
125
  '.': '&dot;',
132
126
  '/': '&slash;',
133
127
  ':': '&colon;',
@@ -135,9 +129,9 @@ const SANTIIZE_PLACEHOLDERS = {
135
129
  function sanitizeFragment(id: string) {
136
130
  // replaces separator characters with placeholders
137
131
  return id
138
- .replace(/[/]/g, SANTIIZE_PLACEHOLDERS['/'])
139
- .replace(/[:]/g, SANTIIZE_PLACEHOLDERS[':'])
140
- .replace(/[.]/g, SANTIIZE_PLACEHOLDERS['.']);
132
+ .replace(/[/]/g, SANITIZE_PLACEHOLDERS['/'])
133
+ .replace(/[:]/g, SANITIZE_PLACEHOLDERS[':'])
134
+ .replace(/[.]/g, SANITIZE_PLACEHOLDERS['.']);
141
135
  }
142
136
  function unsanitizeFragment(id: string) {
143
137
  // replaces placeholders with separator characters