From f2f16c6583da1df429fabdcfe7dba34200c13bdb Mon Sep 17 00:00:00 2001 From: Anton Strogonoff Date: Sun, 10 Jan 2021 14:55:57 +0900 Subject: [PATCH] feat(object specs): simplify extension API (#3) --- src/index.ts | 95 +----------------------------------------- src/types/extension.ts | 19 +-------- 2 files changed, 2 insertions(+), 112 deletions(-) diff --git a/src/index.ts b/src/index.ts index 741b04d..0a939b3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,10 @@ -import path from 'path'; import semver from 'semver'; import 'electron'; import log from 'electron-log'; import { Extension } from './types/extension'; import { ExtensionMaker } from './types/extension-maker'; import { withDatasetContext } from './context'; -import { SerializableObjectSpec, DEFAULT_SPECS, matchesPath } from './object-specs'; -import { stripLeadingSlash } from './util'; +import { DEFAULT_SPECS, matchesPath } from './object-specs'; /* The default export of Paneron extension’s extension.ts entry file @@ -28,97 +26,6 @@ export const makeExtension: ExtensionMaker = async (options) => { return objectSpecs; }, - objectsToBuffers: (objects) => { - const buffers: Record = {}; - for (const [objectPath, obj] of Object.entries(objects)) { - const spec = Object.values(objectSpecs). - find(c => matchesPath(objectPath, c.matches)); - - if (spec) { - const objectBuffersRelative = (spec as SerializableObjectSpec).serialize(obj); - - const objectBuffers: Record = - Object.entries(objectBuffersRelative). - map(([objectRelativePath, data]) => ({ - [path.join(objectPath, objectRelativePath)]: data, - })). - reduce((p, c) => ({ ...p, ...c }), {}); - - Object.assign(buffers, objectBuffers); - } else { - log.error("Unable to find object spec for object path", objectPath); - throw new Error("Unable to find object spec for path"); - } - } - return buffers; - }, - - indexObjects: (rawData) => { - // 1. Go through paths and organize them by matching object spec. - // If a path matches some spec, that path is considered new object root, - // and subsequent paths are considered to belong to this object - // if they are descendants of object root path. - const toProcess: { - objectPath: string - data: Record - spec: SerializableObjectSpec - }[] = []; - - // Sorted paths will appear in fashion [/, /foo/, /foo/bar.yaml, /baz/, /baz/qux.yaml, ...] - const paths = Object.keys(rawData).sort(); - - let currentSpec: SerializableObjectSpec | undefined; - let currentObject: { - path: string - buffers: Record - } | null = null; - - for (const p of paths) { - - if (currentObject && p.startsWith(currentObject.path)) { - // We are in the middle of processing an object - // and current path is a descendant of object’s path. - - // Accumulate current path into current object for deserialization later. - const objectRelativePath = stripLeadingSlash(p.replace(currentObject.path, '')); - currentObject.buffers[`/${objectRelativePath}`] = rawData[p]; - - log.debug("Matched path to object", p, currentObject.path, objectRelativePath); - - } else { - // Were we in the middle of processing a spec and an object? - if (currentSpec && currentObject) { - // If yes, add that spec and accumulated object to list for further processing... - toProcess.push({ - objectPath: currentObject.path, - data: { ...currentObject.buffers }, - spec: currentSpec, - }); - // ...and reset/flush accumulated object. - currentObject = null; - } - - // Find a matching spec for current path. - currentSpec = Object.values(objectSpecs).find(c => matchesPath(p, c.matches)); - - if (currentSpec) { - // If a matching spec was found, start a new object. - currentObject = { path: p, buffers: {} }; - // Current path will be the root path for the object. - currentObject.buffers['/'] = rawData[p]; - } - } - } - - // 2. Deserialize accumulated buffers into objects. - const index: Record> = {}; - for (const { objectPath, data, spec } of toProcess) { - index[objectPath] = spec.deserialize(data); - } - - return index; - }, - getMigration: (datasetVersion) => ( Object.entries(options.datasetMigrations). filter(([migrationVersionSpec, _]) => diff --git a/src/types/extension.ts b/src/types/extension.ts index 025c4b5..35ee9bd 100644 --- a/src/types/extension.ts +++ b/src/types/extension.ts @@ -6,7 +6,6 @@ import { DatasetContext } from './renderer'; /* The interface that extension instance exposes to Paneron in main thread. */ export interface MainPlugin { - // False means another version of the host app must be used (probably a newer one). isCompatible: (withHostAppVersion: string) => boolean @@ -19,25 +18,9 @@ export interface MainPlugin { getInitialMigration: () => MigrationModule getObjectSpecs: () => SerializableObjectSpec[] +} - // TODO: Obsolete - - // Converts buffers with raw file data per path - // to structured records (as JS objects) per path. - // Specs for conversion can be provided to makeExtension to customize - // how object is represented. - // NOTE: Slow, when processing full repository data - // it is supposed to be called from a worker thread only. - indexObjects: (rawData: Record) => - Record> - - // Converts a record that maps paths to object data - // to a record that maps paths to buffers / byte arrays - // ready for storage. - objectsToBuffers: (objects: Record>) => - Record -} /* The interface that extension instance exposes to Paneron in renderer thread. */