@dxos/echo-generator 0.8.2-main.f11618f → 0.8.2-staging.42af850
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/lib/browser/index.mjs +80 -74
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +81 -75
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +80 -74
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/data.d.ts +13 -4
- package/dist/types/src/data.d.ts.map +1 -1
- package/dist/types/src/generator.d.ts +11 -9
- package/dist/types/src/generator.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +5 -4
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -12
- package/src/data.ts +56 -64
- package/src/generator.test.ts +35 -7
- package/src/generator.ts +23 -15
- package/src/types.ts +6 -4
package/src/data.ts
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { next as A } from '@
|
|
5
|
+
import { next as A } from '@automerge/automerge';
|
|
6
|
+
import { Schema } from 'effect';
|
|
7
|
+
|
|
6
8
|
import { createDocAccessor, type Space } from '@dxos/client/echo';
|
|
7
|
-
import {
|
|
8
|
-
import { createEchoSchema, makeRef } from '@dxos/live-object';
|
|
9
|
+
import { EchoObject, Ref } from '@dxos/echo-schema';
|
|
9
10
|
import { faker } from '@dxos/random';
|
|
10
11
|
|
|
11
12
|
import { SpaceObjectGenerator, TestObjectGenerator } from './generator';
|
|
@@ -19,67 +20,49 @@ import { randomText } from './util';
|
|
|
19
20
|
export const Status = ['pending', 'active', 'done'];
|
|
20
21
|
export const Priority = [1, 2, 3, 4, 5];
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated
|
|
25
|
+
*/
|
|
22
26
|
export enum TestSchemaType {
|
|
23
|
-
document = 'example.com/type/
|
|
24
|
-
organization = 'example.com/type/
|
|
25
|
-
contact = 'example.com/type/
|
|
26
|
-
project = 'example.com/type/
|
|
27
|
+
document = 'example.com/type/Document',
|
|
28
|
+
organization = 'example.com/type/Organization',
|
|
29
|
+
contact = 'example.com/type/Contact',
|
|
30
|
+
project = 'example.com/type/Project',
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated
|
|
35
|
+
*/
|
|
29
36
|
const testSchemas = (): TestSchemaMap<TestSchemaType> => {
|
|
30
|
-
const document =
|
|
31
|
-
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
name: S.String.annotations({ description: 'name of the person' }),
|
|
60
|
-
email: S.String,
|
|
61
|
-
org: Ref(organization),
|
|
62
|
-
lat: S.Number,
|
|
63
|
-
lng: S.Number,
|
|
64
|
-
},
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
const project = createEchoSchema(
|
|
68
|
-
{
|
|
69
|
-
typename: TestSchemaType.project,
|
|
70
|
-
version: '0.1.0',
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: S.String.annotations({ description: 'name of the project' }),
|
|
74
|
-
description: S.String,
|
|
75
|
-
website: S.String,
|
|
76
|
-
repo: S.String,
|
|
77
|
-
status: S.String,
|
|
78
|
-
priority: S.Number,
|
|
79
|
-
active: S.Boolean,
|
|
80
|
-
org: Ref(organization),
|
|
81
|
-
},
|
|
82
|
-
);
|
|
37
|
+
const document = Schema.Struct({
|
|
38
|
+
title: Schema.String.annotations({ description: 'title of the document' }),
|
|
39
|
+
content: Schema.String,
|
|
40
|
+
}).pipe(EchoObject({ typename: TestSchemaType.document, version: '0.1.0' }));
|
|
41
|
+
|
|
42
|
+
const organization = Schema.Struct({
|
|
43
|
+
name: Schema.String.annotations({ description: 'name of the company or organization' }),
|
|
44
|
+
website: Schema.optional(Schema.String.annotations({ description: 'public website URL' })),
|
|
45
|
+
description: Schema.String.annotations({ description: 'short summary of the company' }),
|
|
46
|
+
}).pipe(EchoObject({ typename: TestSchemaType.organization, version: '0.1.0' }));
|
|
47
|
+
|
|
48
|
+
const contact = Schema.Struct({
|
|
49
|
+
name: Schema.String.annotations({ description: 'name of the person' }),
|
|
50
|
+
email: Schema.optional(Schema.String),
|
|
51
|
+
org: Schema.optional(Ref(organization)),
|
|
52
|
+
lat: Schema.optional(Schema.Number),
|
|
53
|
+
lng: Schema.optional(Schema.Number),
|
|
54
|
+
}).pipe(EchoObject({ typename: TestSchemaType.contact, version: '0.1.0' }));
|
|
55
|
+
|
|
56
|
+
const project = Schema.Struct({
|
|
57
|
+
name: Schema.String.annotations({ description: 'name of the project' }),
|
|
58
|
+
description: Schema.String,
|
|
59
|
+
website: Schema.String,
|
|
60
|
+
repo: Schema.String,
|
|
61
|
+
status: Schema.String,
|
|
62
|
+
priority: Schema.Number,
|
|
63
|
+
active: Schema.Boolean,
|
|
64
|
+
org: Schema.optional(Ref(organization)),
|
|
65
|
+
}).pipe(EchoObject({ typename: TestSchemaType.project, version: '0.1.0' }));
|
|
83
66
|
|
|
84
67
|
return {
|
|
85
68
|
[TestSchemaType.document]: document,
|
|
@@ -103,13 +86,14 @@ const testObjectGenerators: TestGeneratorMap<TestSchemaType> = {
|
|
|
103
86
|
|
|
104
87
|
[TestSchemaType.contact]: async (provider) => {
|
|
105
88
|
const organizations = await provider?.(TestSchemaType.organization);
|
|
106
|
-
const
|
|
89
|
+
const location = faker.datatype.boolean() ? faker.geo.airport() : {};
|
|
90
|
+
|
|
107
91
|
return {
|
|
108
92
|
name: faker.person.fullName(),
|
|
109
93
|
email: faker.datatype.boolean({ probability: 0.5 }) ? faker.internet.email() : undefined,
|
|
110
94
|
org:
|
|
111
|
-
organizations?.length && faker.datatype.boolean({ probability: 0.
|
|
112
|
-
?
|
|
95
|
+
organizations?.length && faker.datatype.boolean({ probability: 0.8 })
|
|
96
|
+
? Ref.make(faker.helpers.arrayElement(organizations))
|
|
113
97
|
: undefined,
|
|
114
98
|
...location,
|
|
115
99
|
};
|
|
@@ -117,8 +101,10 @@ const testObjectGenerators: TestGeneratorMap<TestSchemaType> = {
|
|
|
117
101
|
|
|
118
102
|
[TestSchemaType.project]: async () => ({
|
|
119
103
|
name: faker.commerce.productName(),
|
|
120
|
-
repo: faker.
|
|
104
|
+
repo: faker.internet.url(),
|
|
121
105
|
status: faker.helpers.arrayElement(Status),
|
|
106
|
+
description: faker.lorem.sentences(),
|
|
107
|
+
website: faker.internet.url(),
|
|
122
108
|
priority: faker.helpers.arrayElement(Priority),
|
|
123
109
|
active: faker.datatype.boolean(),
|
|
124
110
|
}),
|
|
@@ -151,7 +137,13 @@ const testObjectMutators: TestMutationsMap<TestSchemaType> = {
|
|
|
151
137
|
},
|
|
152
138
|
};
|
|
153
139
|
|
|
140
|
+
/**
|
|
141
|
+
* @deprecated Use generators in schema package.
|
|
142
|
+
*/
|
|
154
143
|
export const createTestObjectGenerator = () => new TestObjectGenerator(testSchemas(), testObjectGenerators);
|
|
155
144
|
|
|
145
|
+
/**
|
|
146
|
+
* @deprecated Use generators in schema package.
|
|
147
|
+
*/
|
|
156
148
|
export const createSpaceObjectGenerator = (space: Space) =>
|
|
157
149
|
new SpaceObjectGenerator(space, testSchemas(), testObjectGenerators, testObjectMutators);
|
package/src/generator.test.ts
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { next as A } from '@automerge/automerge';
|
|
6
|
+
import { Schema } from 'effect';
|
|
5
7
|
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
6
8
|
|
|
7
|
-
import { next as A } from '@dxos/automerge/automerge';
|
|
8
9
|
import { Client } from '@dxos/client';
|
|
9
10
|
import { getObjectCore } from '@dxos/echo-db';
|
|
10
|
-
import {
|
|
11
|
+
import { TypedObject } from '@dxos/echo-schema';
|
|
11
12
|
import { getType } from '@dxos/live-object';
|
|
12
13
|
import { faker } from '@dxos/random';
|
|
13
14
|
|
|
@@ -59,14 +60,14 @@ describe('TestObjectGenerator', () => {
|
|
|
59
60
|
const generator = createSpaceObjectGenerator(space);
|
|
60
61
|
await generator.addSchemas();
|
|
61
62
|
const organization = await generator.createObject({ types: [TestSchemaType.organization] });
|
|
62
|
-
schemaId.push(getType(organization)!.
|
|
63
|
+
schemaId.push(getType(organization)!.toString());
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
{
|
|
66
67
|
const generator = createSpaceObjectGenerator(space);
|
|
67
68
|
await generator.addSchemas();
|
|
68
69
|
const organization = await generator.createObject({ types: [TestSchemaType.organization] });
|
|
69
|
-
schemaId.push(getType(organization)!.
|
|
70
|
+
schemaId.push(getType(organization)!.toString());
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
expect(schemaId[0]).not.to.be.undefined;
|
|
@@ -80,14 +81,14 @@ describe('TestObjectGenerator', () => {
|
|
|
80
81
|
const document = await generator.createObject({ types: [TestSchemaType.document] });
|
|
81
82
|
expect(getType(document)).to.exist;
|
|
82
83
|
|
|
83
|
-
const beforeChangesCount = A.getAllChanges(getObjectCore(document).docHandle!.
|
|
84
|
+
const beforeChangesCount = A.getAllChanges(getObjectCore(document).docHandle!.doc()).length;
|
|
84
85
|
|
|
85
86
|
// Mutate the document.
|
|
86
87
|
const mutationsCount = 10;
|
|
87
88
|
await generator.mutateObject(document, { count: mutationsCount, maxContentLength: 1000, mutationSize: 10 });
|
|
88
89
|
await space.db.flush();
|
|
89
90
|
|
|
90
|
-
const changesCount = A.getAllChanges(getObjectCore(document).docHandle!.
|
|
91
|
+
const changesCount = A.getAllChanges(getObjectCore(document).docHandle!.doc()).length;
|
|
91
92
|
expect(changesCount - beforeChangesCount).to.be.eq(mutationsCount);
|
|
92
93
|
});
|
|
93
94
|
|
|
@@ -96,7 +97,7 @@ describe('TestObjectGenerator', () => {
|
|
|
96
97
|
typename: 'example.org/type/Task',
|
|
97
98
|
version: '0.1.0',
|
|
98
99
|
})({
|
|
99
|
-
name:
|
|
100
|
+
name: Schema.optional(Schema.String),
|
|
100
101
|
}) {}
|
|
101
102
|
|
|
102
103
|
enum Types {
|
|
@@ -123,4 +124,31 @@ describe('TestObjectGenerator', () => {
|
|
|
123
124
|
const todo = await generator.createObject({ types: [Types.task] });
|
|
124
125
|
expect(getType(todo)).to.exist;
|
|
125
126
|
});
|
|
127
|
+
|
|
128
|
+
test('references', async () => {
|
|
129
|
+
const { space } = await setupTest();
|
|
130
|
+
const generator = createSpaceObjectGenerator(space);
|
|
131
|
+
await generator.addSchemas();
|
|
132
|
+
|
|
133
|
+
// Create raw object.
|
|
134
|
+
const objects = await generator.createObjects({
|
|
135
|
+
[TestSchemaType.organization]: 1,
|
|
136
|
+
[TestSchemaType.contact]: 1,
|
|
137
|
+
});
|
|
138
|
+
expect(objects).to.exist;
|
|
139
|
+
expect(objects.length).to.be.eq(2);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('create project', async () => {
|
|
143
|
+
const generator = createTestObjectGenerator();
|
|
144
|
+
const project = await generator.createObject({ types: [TestSchemaType.project] });
|
|
145
|
+
expect(getType(project)).to.exist;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('create object with not type', async () => {
|
|
149
|
+
// TODO(burdon): Create Client/spaces.
|
|
150
|
+
const generator = createTestObjectGenerator();
|
|
151
|
+
|
|
152
|
+
await generator.createObject();
|
|
153
|
+
});
|
|
126
154
|
});
|
package/src/generator.ts
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Schema } from 'effect';
|
|
6
|
+
|
|
5
7
|
import { Filter, type Space } from '@dxos/client/echo';
|
|
6
|
-
import { type
|
|
7
|
-
import { getTypeAnnotation, EchoSchema,
|
|
8
|
-
import { getSchema } from '@dxos/echo-schema';
|
|
8
|
+
import { type AnyLiveObject } from '@dxos/echo-db';
|
|
9
|
+
import { getTypeAnnotation, EchoSchema, getSchema } from '@dxos/echo-schema';
|
|
9
10
|
import { invariant } from '@dxos/invariant';
|
|
10
11
|
import { live, isLiveObject, type Live } from '@dxos/live-object';
|
|
11
12
|
import { faker } from '@dxos/random';
|
|
12
|
-
import { range } from '@dxos/util';
|
|
13
|
+
import { entries, range } from '@dxos/util';
|
|
13
14
|
|
|
14
15
|
import { type TestSchemaType } from './data';
|
|
15
16
|
import {
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Typed object generator.
|
|
26
|
+
* @deprecated
|
|
25
27
|
*/
|
|
26
28
|
export class TestObjectGenerator<T extends string = TestSchemaType> {
|
|
27
29
|
// prettier-ignore
|
|
@@ -31,15 +33,15 @@ export class TestObjectGenerator<T extends string = TestSchemaType> {
|
|
|
31
33
|
private readonly _provider?: TestObjectProvider<T>,
|
|
32
34
|
) {}
|
|
33
35
|
|
|
34
|
-
get schemas(): (EchoSchema |
|
|
36
|
+
get schemas(): (EchoSchema | Schema.Schema.AnyNoContext)[] {
|
|
35
37
|
return Object.values(this._schemas);
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
getSchema(type: T): EchoSchema |
|
|
40
|
+
getSchema(type: T): EchoSchema | Schema.Schema.AnyNoContext | undefined {
|
|
39
41
|
return this.schemas.find((schema) => getTypeAnnotation(schema)!.typename === type);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
protected setSchema(type: T, schema: EchoSchema |
|
|
44
|
+
protected setSchema(type: T, schema: EchoSchema | Schema.Schema.AnyNoContext): void {
|
|
43
45
|
this._schemas[type] = schema;
|
|
44
46
|
}
|
|
45
47
|
|
|
@@ -56,6 +58,11 @@ export class TestObjectGenerator<T extends string = TestSchemaType> {
|
|
|
56
58
|
|
|
57
59
|
// TODO(burdon): Based on dependencies (e.g., organization before contact).
|
|
58
60
|
async createObjects(map: Partial<Record<T, number>>) {
|
|
61
|
+
const results: Live<any>[] = [];
|
|
62
|
+
for (const [type, count] of entries(map)) {
|
|
63
|
+
results.push(...(await Promise.all(range(count ?? 0, () => this.createObject({ types: [type as T] })))));
|
|
64
|
+
}
|
|
65
|
+
|
|
59
66
|
const tasks = Object.entries<number>(map as any)
|
|
60
67
|
.map(([type, count]) => {
|
|
61
68
|
return range(count, () => this.createObject({ types: [type as T] }));
|
|
@@ -78,14 +85,15 @@ export class SpaceObjectGenerator<T extends string> extends TestObjectGenerator<
|
|
|
78
85
|
) {
|
|
79
86
|
super(schemaMap, generators, async (type: T) => {
|
|
80
87
|
const schema = this.getSchema(type);
|
|
81
|
-
|
|
88
|
+
const { objects } = await this._space.db.query(schema ? Filter.type(schema) : Filter.nothing()).run();
|
|
89
|
+
return objects;
|
|
82
90
|
});
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
async addSchemas() {
|
|
86
|
-
const result: (EchoSchema |
|
|
94
|
+
const result: (EchoSchema | Schema.Schema.AnyNoContext)[] = [];
|
|
87
95
|
for (const [typename, schema] of Object.entries(this._schemas)) {
|
|
88
|
-
const echoSchema = await this._maybeRegisterSchema(typename, schema as EchoSchema |
|
|
96
|
+
const echoSchema = await this._maybeRegisterSchema(typename, schema as EchoSchema | Schema.Schema.AnyNoContext);
|
|
89
97
|
this.setSchema(typename as T, echoSchema);
|
|
90
98
|
result.push(echoSchema);
|
|
91
99
|
}
|
|
@@ -93,14 +101,14 @@ export class SpaceObjectGenerator<T extends string> extends TestObjectGenerator<
|
|
|
93
101
|
return result;
|
|
94
102
|
}
|
|
95
103
|
|
|
96
|
-
override async createObject({ types }: { types?: T[] } = {}): Promise<
|
|
104
|
+
override async createObject({ types }: { types?: T[] } = {}): Promise<AnyLiveObject<any>> {
|
|
97
105
|
return this._space.db.add(await super.createObject({ types }));
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
private async _maybeRegisterSchema(
|
|
101
109
|
typename: string,
|
|
102
|
-
schema: EchoSchema |
|
|
103
|
-
): Promise<EchoSchema |
|
|
110
|
+
schema: EchoSchema | Schema.Schema.AnyNoContext,
|
|
111
|
+
): Promise<EchoSchema | Schema.Schema.AnyNoContext> {
|
|
104
112
|
if (schema instanceof EchoSchema) {
|
|
105
113
|
const existingSchema = this._space.db.schemaRegistry.getSchema(typename);
|
|
106
114
|
if (existingSchema != null) {
|
|
@@ -118,7 +126,7 @@ export class SpaceObjectGenerator<T extends string> extends TestObjectGenerator<
|
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
|
|
121
|
-
async mutateObject(object:
|
|
129
|
+
async mutateObject(object: AnyLiveObject<any>, params: MutationsProviderParams): Promise<void> {
|
|
122
130
|
invariant(this._mutations, 'Mutations not defined.');
|
|
123
131
|
const type = getTypeAnnotation(getSchema(object)!)!.typename as T;
|
|
124
132
|
invariant(type && this._mutations?.[type], 'Invalid object type.');
|
|
@@ -126,7 +134,7 @@ export class SpaceObjectGenerator<T extends string> extends TestObjectGenerator<
|
|
|
126
134
|
await this._mutations;
|
|
127
135
|
}
|
|
128
136
|
|
|
129
|
-
async mutateObjects(objects:
|
|
137
|
+
async mutateObjects(objects: AnyLiveObject<any>[], params: MutationsProviderParams): Promise<void> {
|
|
130
138
|
for (const object of objects) {
|
|
131
139
|
await this.mutateObject(object, params);
|
|
132
140
|
}
|
package/src/types.ts
CHANGED
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type
|
|
6
|
-
|
|
5
|
+
import { type Schema } from 'effect';
|
|
6
|
+
|
|
7
|
+
import { type AnyLiveObject } from '@dxos/echo-db';
|
|
8
|
+
import { type EchoSchema } from '@dxos/echo-schema';
|
|
7
9
|
import { type Live } from '@dxos/live-object';
|
|
8
10
|
|
|
9
11
|
// TODO(burdon): Use echo-schema types.
|
|
10
12
|
export type TestObject = { id: string } & Record<string, any>;
|
|
11
13
|
|
|
12
|
-
export type TestSchemaMap<T extends string = string> = Record<T, EchoSchema |
|
|
14
|
+
export type TestSchemaMap<T extends string = string> = Record<T, EchoSchema | Schema.Schema.AnyNoContext>;
|
|
13
15
|
|
|
14
16
|
export type TestObjectProvider<T extends string = string> = (type: T) => Promise<Live<any>[]>;
|
|
15
17
|
|
|
@@ -26,4 +28,4 @@ export type MutationsProviderParams = {
|
|
|
26
28
|
maxContentLength: number;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
|
-
export type TestObjectMutators = (object:
|
|
31
|
+
export type TestObjectMutators = (object: AnyLiveObject<any>, params: MutationsProviderParams) => Promise<void>;
|