Skip to content

Commit

Permalink
Add JSON document combining logic (#744)
Browse files Browse the repository at this point in the history
  • Loading branch information
lyonsil authored Feb 2, 2024
1 parent 99c065a commit e08d669
Show file tree
Hide file tree
Showing 21 changed files with 7,188 additions and 1,947 deletions.
8 changes: 6 additions & 2 deletions extensions/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion lib/papi-dts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions lib/platform-bible-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
"lint:scripts": "cross-env NODE_ENV=development eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .",
"lint:styles": "stylelint **/*.{css,scss}",
"lint-fix": "npm run lint-fix:scripts && npm run lint:styles -- --fix",
"lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts",
"postinstall": "cd ../.. && npm install --ignore-scripts"
"lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts"
},
"peerDependencies": {
"react": ">=18.2.0",
Expand Down
16 changes: 16 additions & 0 deletions lib/platform-bible-utils/.babelrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"sourceType": "unambiguous",
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": 100
}
}
],
"@babel/preset-typescript",
"@babel/preset-react"
],
"plugins": []
}
2 changes: 1 addition & 1 deletion lib/platform-bible-utils/dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/platform-bible-utils/dist/index.cjs.map

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions lib/platform-bible-utils/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,100 @@ export declare class AsyncVariable<T> {
/** Prevent any further updates to this variable */
private complete;
}
export type JsonDocumentLike = {
[key: string]: unknown;
};
/**
* Options for DocumentCombinerEngine objects
*
* - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before
* composing the output. If false, then changes made to provided documents after they are
* contributed will be reflected in the next time output is composed.
* - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in
* contributed documents. If false, then throw when duplicate properties are seen in contributed
* documents.
*/
export type DocumentCombinerOptions = {
copyDocuments: boolean;
ignoreDuplicateProperties: boolean;
};
/**
* Base class for any code that wants to compose JSON documents (in the form of JS objects) together
* into a single output document.
*/
export declare abstract class DocumentCombinerEngine {
protected baseDocument: JsonDocumentLike;
protected readonly contributions: Map<string, JsonDocumentLike>;
protected latestOutput: JsonDocumentLike | undefined;
protected readonly options: DocumentCombinerOptions;
/**
* Create a DocumentCombinerEngine instance
*
* @param baseDocument This is the first document that will be used when composing the output
* @param copyDocuments If true, this instance will perform a deep copy of all provided documents
* before composing the output. If false, then changes made to provided documents after they are
* contributed will be reflected in the next time output is composed.
*/
protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions);
/**
* Update the starting document for composition process
*
* @param baseDocument Base JSON document/JS object that all other documents are added to
* @returns Recalculated output document given the new starting state and existing other documents
*/
updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined;
/**
* Add or update one of the contribution documents for the composition process
*
* @param documentName Name of the contributed document to combine
* @param document Content of the contributed document to combine
* @returns Recalculated output document given the new or updated contribution and existing other
* documents
*/
addOrUpdateContribution(documentName: string, document: JsonDocumentLike): JsonDocumentLike | undefined;
/**
* Delete one of the contribution documents for the composition process
*
* @param documentName Name of the contributed document to delete
* @returns Recalculated output document given the remaining other documents
*/
deleteContribution(documentName: string): object | undefined;
/**
* Run the document composition process given the starting document and all contributions. Throws
* if the output document fails to validate properly.
*
* @returns Recalculated output document given the starting and contributed documents
*/
rebuild(): JsonDocumentLike | undefined;
/**
* Throw an error if the provided document is not a valid starting document.
*
* @param baseDocument Base JSON document/JS object that all other documents are added to
*/
protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;
/**
* Throw an error if the provided document is not a valid contribution document.
*
* @param documentName Name of the contributed document to combine
* @param document Content of the contributed document to combine
*/
protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;
/**
* Throw an error if the provided output is not valid.
*
* @param output Output document that could potentially be returned to callers
*/
protected abstract validateOutput(output: JsonDocumentLike): void;
/**
* Transform the document that is the composition of the base document and all contribution
* documents. This is the last step that will be run prior to validation before
* `this.latestOutput` is updated to the new output.
*
* @param finalOutput Final output document that could potentially be returned to callers. "Final"
* means no further contribution documents will be merged.
*/
protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;
}
/** Function to run to dispose of something. Returns true if successfully unsubscribed */
export type Unsubscriber = () => boolean;
/**
Expand Down Expand Up @@ -204,6 +298,14 @@ export declare function newGuid(): string;
* @returns True if the object is a string; false otherwise
*/
export declare function isString(o: unknown): o is string;
/**
* If deepClone isn't used when copying properties between objects, you may be left with dangling
* references between the source and target of property copying operations.
*
* @param obj Object to clone
* @returns Duplicate copy of `obj` without any references back to the original one
*/
export declare function deepClone<T>(obj: T): T;
/**
* Get a function that reduces calls to the function passed in
*
Expand Down
Loading

0 comments on commit e08d669

Please sign in to comment.