Skip to content

Commit

Permalink
Remove dependency on Type from Schema (PolymerLabs#4191)
Browse files Browse the repository at this point in the history
  • Loading branch information
raulverag authored Nov 28, 2019
1 parent 8f96ecd commit c28029d
Show file tree
Hide file tree
Showing 30 changed files with 157 additions and 126 deletions.
3 changes: 2 additions & 1 deletion shells/lib/context-stores.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

import {Reference} from '../../build/runtime/reference.js';
import {EntityType} from '../../build/runtime/type.js';
import {crackStorageKey, simpleNameOfType} from './context-utils.js';
import {Stores} from './stores.js';

Expand Down Expand Up @@ -65,7 +66,7 @@ const ContextStoresImpl = class {
store.remove(`shared-${entity.id}`);
}
async createReferenceStore(context, schema, name, id, tags) {
const type = schema.type.collectionOf();
const type = (new EntityType(schema)).collectionOf();
const store = await Stores.createStore(context, type, {name, id: `${id}`, tags});
return store;
}
Expand Down
3 changes: 2 additions & 1 deletion shells/lib/shares.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import {Stores} from './stores.js';
import {logsFactory} from '../../build/platform/logs-factory.js';
import {EntityType} from '../../build/runtime/type.js';

const {log} = logsFactory('Shares', '#999900');

Expand All @@ -35,7 +36,7 @@ export const initShares = context => {
};

const createShare = async (context, name, schema) => {
const type = schema.type.collectionOf();
const type = (new EntityType(schema)).collectionOf();
await Stores.requireStore(context, type, {
name,
id: name,
Expand Down
3 changes: 2 additions & 1 deletion shells/web-shell/elements/web-shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import {linkJack} from '../../../modalities/dom/components/link-jack.js';
import {generateId} from '../../../modalities/dom/components/generate-id.js';
import {Runtime} from '../../../build/runtime/runtime.js';
import {EntityType} from '../../../build/runtime/type.js';
import {logsFactory} from '../../../build/platform/logs-factory.js';
import {Const} from '../../configuration/constants.js';
import {Xen} from '../../lib/components/xen.js';
Expand Down Expand Up @@ -189,7 +190,7 @@ export class WebShell extends Xen.Debug(Xen.Async, log) {
const {context, launcherArc, store} = this.state;
if (context && launcherArc && !store) {
const shareSchema = context.findSchemaByName('ArcMeta');
const store = launcherArc.findStoresByType(shareSchema.type.collectionOf()).pop();
const store = launcherArc.findStoresByType(new EntityType(shareSchema).collectionOf()).pop();
if (store) {
this.state = {store: store};
store.on(info => this.state = {info});
Expand Down
4 changes: 3 additions & 1 deletion src/devtools-connector/tests/arc-stores-fetcher-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {SingletonType} from '../../runtime/type.js';
import {singletonHandleForTest, storageKeyPrefixForTest} from '../../runtime/testing/handle-for-test.js';
import {Flags} from '../../runtime/flags.js';

import {Entity} from '../../runtime/entity.js';

describe('ArcStoresFetcher', () => {
before(() => DevtoolsForTests.ensureStub());
after(() => DevtoolsForTests.reset());
Expand All @@ -30,7 +32,7 @@ describe('ArcStoresFetcher', () => {
const runtime = new Runtime(new StubLoader({}), FakeSlotComposer, context);
const arc = runtime.newArc('demo', storageKeyPrefixForTest(), {inspectorFactory: devtoolsArcInspectorFactory});

const foo = arc.context.findSchemaByName('Foo').entityClass();
const foo = Entity.createEntityClass(arc.context.findSchemaByName('Foo'), null);
const fooStore = await arc.createStore(new SingletonType(foo.type), 'fooStoreName', 'fooStoreId', ['awesome', 'arcs']);
const fooHandle = await singletonHandleForTest(arc, fooStore);
await fooHandle.set(new foo({value: 'persistence is useful'}));
Expand Down
4 changes: 3 additions & 1 deletion src/devtools-connector/tests/devtools-arc-inspector-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {Manifest} from '../../runtime/manifest.js';
import {Runtime} from '../../runtime/runtime.js';
import {storageKeyPrefixForTest} from '../../runtime/testing/handle-for-test.js';

import {Entity} from '../../runtime/entity.js';

describe('DevtoolsArcInspector', () => {
before(() => DevtoolsForTests.ensureStub());
after(() => DevtoolsForTests.reset());
Expand All @@ -41,7 +43,7 @@ describe('DevtoolsArcInspector', () => {
const runtime = new Runtime(loader, MockSlotComposer, context);
const arc = runtime.newArc('demo', storageKeyPrefixForTest(), {inspectorFactory: devtoolsArcInspectorFactory});

const foo = arc.context.findSchemaByName('Foo').entityClass();
const foo = Entity.createEntityClass(arc.context.findSchemaByName('Foo'), null);
const fooStore = await arc.createStore(foo.type, undefined, 'fooStore');

const recipe = arc.context.recipes[0];
Expand Down
4 changes: 3 additions & 1 deletion src/planning/strategies/tests/init-population-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {InitPopulation} from '../../strategies/init-population.js';
import {StrategyTestHelper} from '../../testing/strategy-test-helper.js';
import {ArcId} from '../../../runtime/id.js';

import {Entity} from '../../../runtime/entity.js';

describe('InitPopulation', () => {
it('penalizes resolution of particles that already exist in the arc', async () => {
const manifest = await Manifest.parse(`
Expand Down Expand Up @@ -128,7 +130,7 @@ describe('InitPopulation', () => {

async function openRestaurantWith(foodType) {
const restaurant = manifest.recipes.find(recipe => recipe.name === `${foodType}Restaurant`);
const foodEntity = manifest.findSchemaByName(foodType).entityClass();
const foodEntity = Entity.createEntityClass(manifest.findSchemaByName(foodType), null);
const store = await arc.createStore(foodEntity.type, undefined, `test:${foodType}`);
restaurant.handles[0].mapToStorage(store);
restaurant.normalize();
Expand Down
6 changes: 4 additions & 2 deletions src/planning/strategies/tests/match-particle-by-verb-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {MatchParticleByVerb} from '../../strategies/match-particle-by-verb.js';

import {StrategyTestHelper} from '../../testing/strategy-test-helper.js';

import {Entity} from '../../../runtime/entity.js';

describe('MatchParticleByVerb', () => {
const manifestStr = `
schema Energy
Expand Down Expand Up @@ -65,8 +67,8 @@ describe('MatchParticleByVerb', () => {
it('particles by verb recipe fully resolved', async () => {
const manifest = (await Manifest.parse(manifestStr));
const recipe = manifest.recipes[0];
recipe.handles[0].mapToStorage({id: 'test1', type: manifest.findSchemaByName('Height').entityClass().type});
recipe.handles[1].mapToStorage({id: 'test2', type: manifest.findSchemaByName('Energy').entityClass().type});
recipe.handles[0].mapToStorage({id: 'test1', type: Entity.createEntityClass(manifest.findSchemaByName('Height'), null).type});
recipe.handles[1].mapToStorage({id: 'test2', type: Entity.createEntityClass(manifest.findSchemaByName('Energy'), null).type});

const arc = StrategyTestHelper.createTestArc(manifest, {modalityName: Modality.Name.Dom});

Expand Down
3 changes: 2 additions & 1 deletion src/planning/strategies/tests/resolve-recipe-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {Manifest} from '../../../runtime/manifest.js';
import {ResolveRecipe} from '../../strategies/resolve-recipe.js';

import {StrategyTestHelper} from '../../testing/strategy-test-helper.js';
import {Entity} from '../../../runtime/entity.js';

const {createTestArc, onlyResult, theResults, noResult} = StrategyTestHelper;

Expand Down Expand Up @@ -222,7 +223,7 @@ describe('resolve recipe', () => {

const arc = createTestArc(manifest);

const car = manifest.findSchemaByName('Car').entityClass();
const car = Entity.createEntityClass(manifest.findSchemaByName('Car'), null);
await arc.createStore(car.type, /* name= */ null, 'batmobile');

const recipe = manifest.recipes[0];
Expand Down
12 changes: 7 additions & 5 deletions src/planning/tests/planner-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {Id, ArcId} from '../../runtime/id.js';
import {Flags} from '../../runtime/flags.js';
import {StorageKey} from '../../runtime/storageNG/storage-key.js';
import {RamDiskStorageKey} from '../../runtime/storageNG/drivers/ramdisk.js';
import {EntityType} from '../../runtime/type.js';
import {Entity} from '../../runtime/entity.js';

async function planFromManifest(manifest, {arcFactory, testSteps}: {arcFactory?, testSteps?} = {}) {
const loader = new Loader();
Expand Down Expand Up @@ -387,21 +389,21 @@ ${recipeManifest}

const schema = manifest.findSchemaByName('Foo');
manifest.newStore({
type: schema.type.collectionOf(),
type: new EntityType(schema).collectionOf(),
name: 'Test1',
id: 'test-1',
storageKey: key('storage-key-1'),
tags: ['tag1'],
});
manifest.newStore({
type: schema.type.collectionOf(),
type: new EntityType(schema).collectionOf(),
name: 'Test2',
id: 'test-2',
storageKey: key('storage-key-2'),
tags: ['tag2'],
});
manifest.newStore({
type: schema.type.collectionOf(),
type: new EntityType(schema).collectionOf(),
name: 'Test2',
id: 'test-3',
storageKey: key('storage-key-3'),
Expand Down Expand Up @@ -972,7 +974,7 @@ describe('Automatic resolution', () => {
A
`,
async (arc, manifest) => {
const thing = manifest.findSchemaByName('Thing').entityClass();
const thing = Entity.createEntityClass(manifest.findSchemaByName('Thing'), null);
await arc.createStore(thing.type, undefined, 'test:1');
}
);
Expand Down Expand Up @@ -1038,7 +1040,7 @@ describe('Automatic resolution', () => {
item: consumes Slot`,
async (arcRef, manifest) => {
arc = arcRef;
const thing = manifest.findSchemaByName('Thing').entityClass();
const thing = Entity.createEntityClass(manifest.findSchemaByName('Thing'), null);
await arc.createStore(thing.type.collectionOf(), undefined, 'test-store', ['items']);
});

Expand Down
1 change: 1 addition & 0 deletions src/platform/loader-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {UiMultiplexerParticle} from '../runtime/ui-multiplexer-particle.js';
import {html} from '../runtime/html.js';
import {logsFactory} from '../platform/logs-factory.js';
import {Dictionary} from '../runtime/hot.js';
import '../runtime/schema-from-literal.js';

type ParticleCtor = typeof Particle;

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ export function handleFor(storage: Store, idGenerator: IdGenerator, name: string

const schema = storage.type.getEntitySchema();
if (schema) {
handle.entityClass = schema.entityClass(storage.pec);
handle.entityClass = Entity.createEntityClass(schema, storage.pec);
}
return handle;
}
Expand Down
35 changes: 35 additions & 0 deletions src/runtime/schema-from-literal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @license
* Copyright (c) 2017 Google Inc. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* Code distributed by Google as part of this project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/

import {Schema} from './schema.js';
import {Type} from './type.js';

function fromLiteral(data = {fields: {}, names: [], description: {}}) {
const fields = {};
const updateField = field => {
if (field.kind === 'schema-reference') {
const schema = field.schema;
return {kind: 'schema-reference', schema: {kind: schema.kind, model: Type.fromLiteral(schema.model)}};
} else if (field.kind === 'schema-collection') {
return {kind: 'schema-collection', schema: updateField(field.schema)};
} else {
return field;
}
};
for (const key of Object.keys(data.fields)) {
fields[key] = updateField(data.fields[key]);
}

const result = new Schema(data.names, fields);
result.description = data.description || {};
return result;
}

Schema.fromLiteral = fromLiteral;
37 changes: 6 additions & 31 deletions src/runtime/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@
* http://polymer.github.io/PATENTS.txt
*/

import {EntityClass, Entity} from './entity.js';
import {ParticleExecutionContext} from './particle-execution-context.js';
import {EntityType, Type} from './type.js';
import {Dictionary} from './hot.js';
import {CRDTEntity, SingletonEntityModel, CollectionEntityModel} from './crdt/crdt-entity.js';
import {Referenceable} from './crdt/crdt-collection.js';
import {CRDTSingleton} from './crdt/crdt-singleton.js';
import {Flags} from './flags.js';

// tslint:disable-next-line: no-any
type SchemaMethod = (data?: { fields: {}; names: any[]; description: {}; }) => Schema;

export class Schema {
readonly names: string[];
// tslint:disable-next-line: no-any
readonly fields: Dictionary<any>;
description: Dictionary<string> = {};
isAlias: boolean;
// The implementation of fromLiteral creates a cyclic dependency, so it is
// separated out. This variable serves the purpose of an abstract static.
static fromLiteral: SchemaMethod = null;

// For convenience, primitive field types can be specified as {name: 'Type'}
// in `fields`; the constructor will convert these to the correct schema form.
Expand Down Expand Up @@ -61,27 +65,6 @@ export class Schema {
return {names: this.names, fields, description: this.description};
}

static fromLiteral(data = {fields: {}, names: [], description: {}}) {
const fields = {};
const updateField = field => {
if (field.kind === 'schema-reference') {
const schema = field.schema;
return {kind: 'schema-reference', schema: {kind: schema.kind, model: Type.fromLiteral(schema.model)}};
} else if (field.kind === 'schema-collection') {
return {kind: 'schema-collection', schema: updateField(field.schema)};
} else {
return field;
}
};
for (const key of Object.keys(data.fields)) {
fields[key] = updateField(data.fields[key]);
}

const result = new Schema(data.names, fields);
result.description = data.description || {};
return result;
}

// TODO(cypher1): This should only be an ident used in manifest parsing.
get name() {
return this.names[0];
Expand Down Expand Up @@ -172,14 +155,6 @@ export class Schema {
return true;
}

get type(): Type {
return new EntityType(this);
}

entityClass(context: ParticleExecutionContext|null = null): EntityClass {
return Entity.createEntityClass(this, context);
}

crdtConstructor<S extends Dictionary<Referenceable>, C extends Dictionary<Referenceable>>() {
const singletons = {};
const collections = {};
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/storageNG/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export abstract class PreEntityMutationHandle<T extends CRDTTypeRecord> extends

const type = this.storageProxy.type.getContainedType() || this.storageProxy.type;
if (type instanceof EntityType) {
this.entityClass = type.entitySchema.entityClass();
this.entityClass = Entity.createEntityClass(type.entitySchema, null);
} else {
throw new Error(`can't construct handle for entity mutation if type is not an entity type`);
}
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/storageNG/tests/handle-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ describe('CollectionHandle', async () => {
before(async () => {
const loader = new Loader();
const manifest = await Manifest.load('./src/runtime/tests/artifacts/test-particles.manifest', loader);
barType = manifest.schemas.Bar.type as EntityType;
Bar = barType.getEntitySchema().entityClass();
barType = new EntityType(manifest.schemas.Bar);
Bar = Entity.createEntityClass(barType.getEntitySchema(), null);
});

it('can add and remove elements', async () => {
Expand Down
Loading

0 comments on commit c28029d

Please sign in to comment.