mock-block-dock
Advanced tools
Comparing version 0.0.8 to 0.0.9
@@ -6,2 +6,3 @@ "use strict"; | ||
var entityTypes_1 = require("./entityTypes"); | ||
var linkedAggregationDefinitions_1 = require("./linkedAggregationDefinitions"); | ||
var links_1 = require("./links"); | ||
@@ -12,3 +13,4 @@ exports.mockData = { | ||
links: links_1.links, | ||
linkedAggregationDefinitions: linkedAggregationDefinitions_1.linkedAggregationDefinitions, | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -0,3 +1,3 @@ | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolLink, BlockProtocolLinkedAggregationDefinition } from "blockprotocol"; | ||
import { ReactElement, VoidFunctionComponent } from "react"; | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolLink } from "blockprotocol"; | ||
declare type MockBlockDockProps = { | ||
@@ -9,4 +9,16 @@ children: ReactElement; | ||
initialLinks?: BlockProtocolLink[]; | ||
initialLinkedAggregations?: BlockProtocolLinkedAggregationDefinition[]; | ||
}; | ||
/** | ||
* A component to wrap a Block Protocol block, acting as a mock embedding application. | ||
* It provides the functions specified in the Block Protocol, and mock data which can be customized via props. | ||
* See README.md for usage instructions. | ||
* @param children the block component to be provided mock data and functions, with any starting props | ||
* @param [blockSchema] - The schema for the block entity | ||
* @param [initialEntities] - The entities to include in the data store (NOT the block entity, which is always provided) | ||
* @param [initialEntityTypes] - The entity types to include in the data store (NOT the block's type, which is always provided) | ||
* @param [initialLinks] - The links to include in the data store | ||
* @param [initialLinkedAggregations] - The linkedAggregation DEFINITIONS to include in the data store (results will be resolved automatically) | ||
*/ | ||
export declare const MockBlockDock: VoidFunctionComponent<MockBlockDockProps>; | ||
export {}; |
@@ -16,11 +16,21 @@ "use strict"; | ||
var react_1 = require("react"); | ||
var useMockDatastore_1 = require("./useMockDatastore"); | ||
var data_1 = require("./data"); | ||
var useLinkFields_1 = require("./useLinkFields"); | ||
var useMockDatastore_1 = require("./useMockDatastore"); | ||
/** | ||
* A component to wrap a Block Protocol block, acting as a mock embedding application. | ||
* It provides the functions specified in the Block Protocol, and mock data which can be customized via props. | ||
* See README.md for usage instructions. | ||
* @param children the block component to be provided mock data and functions, with any starting props | ||
* @param [blockSchema] - The schema for the block entity | ||
* @param [initialEntities] - The entities to include in the data store (NOT the block entity, which is always provided) | ||
* @param [initialEntityTypes] - The entity types to include in the data store (NOT the block's type, which is always provided) | ||
* @param [initialLinks] - The links to include in the data store | ||
* @param [initialLinkedAggregations] - The linkedAggregation DEFINITIONS to include in the data store (results will be resolved automatically) | ||
*/ | ||
var MockBlockDock = function (_a) { | ||
var children = _a.children, blockSchema = _a.blockSchema, initialEntities = _a.initialEntities, initialEntityTypes = _a.initialEntityTypes, initialLinks = _a.initialLinks; | ||
var children = _a.children, blockSchema = _a.blockSchema, initialEntities = _a.initialEntities, initialEntityTypes = _a.initialEntityTypes, initialLinks = _a.initialLinks, initialLinkedAggregations = _a.initialLinkedAggregations; | ||
var mockData = (0, react_1.useMemo)(function () { | ||
var _a; | ||
var blockEntityType = __assign({ entityTypeId: "blockType1", title: "BlockType", type: "object", $schema: "https://json-schema.org/draft/2019-09/schema", $id: "http://localhost/blockType1" }, (blockSchema !== null && blockSchema !== void 0 ? blockSchema : {})); | ||
var accountId = (_a = children.props.accountId) !== null && _a !== void 0 ? _a : "accountId"; | ||
var accountId = children.props.accountId; | ||
var initialBlockEntity = { | ||
@@ -42,2 +52,3 @@ accountId: accountId, | ||
links: initialLinks !== null && initialLinks !== void 0 ? initialLinks : data_1.mockData.links, | ||
linkedAggregationDefinitions: initialLinkedAggregations !== null && initialLinkedAggregations !== void 0 ? initialLinkedAggregations : data_1.mockData.linkedAggregationDefinitions, | ||
}; | ||
@@ -52,8 +63,11 @@ nextMockData.entities.push(initialBlockEntity); | ||
initialLinks, | ||
initialLinkedAggregations, | ||
children.props, | ||
]); | ||
var _b = (0, useMockDatastore_1.useMockDatastore)(mockData), entities = _b.entities, entityTypes = _b.entityTypes, links = _b.links, functions = _b.functions; | ||
var _b = (0, useMockDatastore_1.useMockDatastore)(mockData), entities = _b.entities, entityTypes = _b.entityTypes, links = _b.links, linkedAggregationDefinitions = _b.linkedAggregationDefinitions, functions = _b.functions; | ||
var latestBlockEntity = (0, react_1.useMemo)(function () { | ||
var _a; | ||
return ((_a = entities.find(function (entity) { return entity.entityId === children.props.entityId; })) !== null && _a !== void 0 ? _a : mockData.entities.find(function (entity) { return entity.entityId === children.props.entityId; })); | ||
return ((_a = entities.find(function (entity) { return entity.entityId === children.props.entityId; })) !== null && _a !== void 0 ? _a : | ||
// fallback in case the entityId of the wrapped component is updated by updating its props | ||
mockData.entities.find(function (entity) { return entity.entityId === children.props.entityId; })); | ||
}, [entities, children.props.entityId, mockData.entities]); | ||
@@ -65,2 +79,3 @@ if (!latestBlockEntity) { | ||
var updateEntities = functions.updateEntities; | ||
// watch for changes to the props provided to the wrapped component, and update the associated entity if they change | ||
var prevChildPropsString = (0, react_1.useRef)(JSON.stringify(children.props)); | ||
@@ -75,7 +90,10 @@ (0, react_1.useEffect)(function () { | ||
}, [accountId, entityId, entityTypeId, children.props, updateEntities]); | ||
// construct BP-specified link fields from the links and linkedAggregations in the datastore | ||
var _c = (0, useLinkFields_1.useLinkFields)({ | ||
entities: entities, | ||
links: links, | ||
linkedAggregationDefinitions: linkedAggregationDefinitions, | ||
startingEntity: latestBlockEntity, | ||
}), linkedAggregations = _c.linkedAggregations, linkedEntities = _c.linkedEntities, linkGroups = _c.linkGroups; | ||
// @todo we don't do anything with this type except check it exists - do we need to do this? | ||
var latestBlockEntityType = (0, react_1.useMemo)(function () { | ||
@@ -82,0 +100,0 @@ return entityTypes.find(function (entityType) { |
@@ -1,2 +0,2 @@ | ||
import { BlockProtocolEntity, BlockProtocolLink, BlockProtocolLinkGroup, BlockProtocolProps } from "blockprotocol"; | ||
import { BlockProtocolEntity, BlockProtocolLink, BlockProtocolLinkedAggregationDefinition, BlockProtocolLinkGroup, BlockProtocolProps } from "blockprotocol"; | ||
declare type LinkFields = { | ||
@@ -7,8 +7,9 @@ linkedAggregations: BlockProtocolProps["linkedAggregations"]; | ||
}; | ||
export declare const useLinkFields: ({ entities, links, startingEntity, }: { | ||
export declare const useLinkFields: ({ entities, links, linkedAggregationDefinitions, startingEntity, }: { | ||
depth?: number | undefined; | ||
entities: BlockProtocolEntity[]; | ||
links: BlockProtocolLink[]; | ||
linkedAggregationDefinitions: BlockProtocolLinkedAggregationDefinition[]; | ||
startingEntity: BlockProtocolEntity; | ||
}) => LinkFields; | ||
export {}; |
@@ -18,3 +18,3 @@ "use strict"; | ||
var useLinkFields = function (_a) { | ||
var entities = _a.entities, links = _a.links, startingEntity = _a.startingEntity; | ||
var entities = _a.entities, links = _a.links, linkedAggregationDefinitions = _a.linkedAggregationDefinitions, startingEntity = _a.startingEntity; | ||
// @todo optionally resolve to further depth, i.e. follow links from linked entities | ||
@@ -24,26 +24,24 @@ var _b = (0, react_1.useMemo)(function () { | ||
var sourceAccountId = _a.sourceAccountId, sourceEntityId = _a.sourceEntityId, sourceEntityTypeId = _a.sourceEntityTypeId; | ||
return (0, util_1.matchIdentifiers)({ | ||
accountId: sourceAccountId, | ||
entityId: sourceEntityId, | ||
entityTypeId: sourceEntityTypeId, | ||
}, startingEntity); | ||
return (0, util_1.matchEntityIdentifiers)({ | ||
providedIdentifiers: { | ||
accountId: sourceAccountId, | ||
entityId: sourceEntityId, | ||
entityTypeId: sourceEntityTypeId, | ||
}, | ||
entityToCheck: startingEntity, | ||
}); | ||
}); | ||
var calculatedLinkGroups = linksFromStartingEntity.reduce(function (linkGroupsAcc, link) { | ||
if ("operation" in link) { | ||
/** | ||
* this is an aggregation link - they don't go in linkGroups, | ||
* because they are in linkedAggregations | ||
* @todo should they be in linkGroups too? | ||
* */ | ||
return linkGroupsAcc; | ||
} | ||
var existingGroup = linkGroupsAcc.find(function (group) { | ||
return (0, util_1.matchIdentifiers)({ | ||
accountId: link.sourceAccountId, | ||
entityId: link.sourceEntityId, | ||
entityTypeId: link.sourceEntityTypeId, | ||
}, { | ||
accountId: group.sourceAccountId, | ||
entityId: group.sourceEntityId, | ||
entityTypeId: group.sourceEntityTypeId, | ||
return (0, util_1.matchEntityIdentifiers)({ | ||
providedIdentifiers: { | ||
accountId: link.sourceAccountId, | ||
entityId: link.sourceEntityId, | ||
entityTypeId: link.sourceEntityTypeId, | ||
}, | ||
entityToCheck: { | ||
accountId: group.sourceAccountId, | ||
entityId: group.sourceEntityId, | ||
entityTypeId: group.sourceEntityTypeId, | ||
}, | ||
}) && link.path === group.path; | ||
@@ -67,29 +65,37 @@ }); | ||
return linksFromStartingEntity.find(function (link) { | ||
return "destinationEntityId" in link && | ||
(0, util_1.matchIdentifiers)({ | ||
return (0, util_1.matchEntityIdentifiers)({ | ||
providedIdentifiers: { | ||
accountId: link.destinationAccountId, | ||
entityId: link.destinationEntityId, | ||
entityTypeId: link.destinationEntityTypeId, | ||
}, entity); | ||
}, | ||
entityToCheck: entity, | ||
}); | ||
}); | ||
}); | ||
var calculatedLinkedAggregations = linksFromStartingEntity | ||
.map(function (link) { | ||
if (!("operation" in link)) { | ||
var calculatedLinkedAggregations = linkedAggregationDefinitions | ||
.map(function (linkedAggregation) { | ||
var isLinkedFromStartingEntity = (0, util_1.matchEntityIdentifiers)({ | ||
providedIdentifiers: { | ||
accountId: linkedAggregation.sourceAccountId, | ||
entityId: linkedAggregation.sourceEntityId, | ||
entityTypeId: linkedAggregation.sourceEntityTypeId, | ||
}, | ||
entityToCheck: startingEntity, | ||
}); | ||
if (!isLinkedFromStartingEntity) { | ||
return null; | ||
} | ||
var results = (0, util_1.filterAndSortEntitiesOrTypes)(entities, { | ||
operation: link.operation, | ||
}); | ||
return __assign(__assign({}, link), results); | ||
var results = (0, util_1.filterAndSortEntitiesOrTypes)(entities, linkedAggregation); | ||
return __assign(__assign({}, linkedAggregation), results); | ||
}) | ||
.filter(function (thing) { return thing !== null; }); | ||
return { | ||
linkedAggregations: calculatedLinkedAggregations, | ||
resolvedLinkedAggregations: calculatedLinkedAggregations, | ||
linkedEntities: calculatedLinkedEntities, | ||
linkGroups: calculatedLinkGroups, | ||
}; | ||
}, [entities, links, startingEntity]), linkedAggregations = _b.linkedAggregations, linkedEntities = _b.linkedEntities, linkGroups = _b.linkGroups; | ||
}, [entities, links, linkedAggregationDefinitions, startingEntity]), resolvedLinkedAggregations = _b.resolvedLinkedAggregations, linkedEntities = _b.linkedEntities, linkGroups = _b.linkGroups; | ||
return { | ||
linkedAggregations: linkedAggregations, | ||
linkedAggregations: resolvedLinkedAggregations, | ||
linkGroups: linkGroups, | ||
@@ -96,0 +102,0 @@ linkedEntities: linkedEntities, |
@@ -1,11 +0,12 @@ | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolFunctions, BlockProtocolLink } from "blockprotocol"; | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolFunctions, BlockProtocolLink, BlockProtocolLinkedAggregationDefinition } from "blockprotocol"; | ||
export declare type MockData = { | ||
entities: BlockProtocolEntity[]; | ||
links: BlockProtocolLink[]; | ||
linkedAggregationDefinitions: BlockProtocolLinkedAggregationDefinition[]; | ||
entityTypes: BlockProtocolEntityType[]; | ||
}; | ||
declare type MockDataStore = MockData & { | ||
functions: Omit<BlockProtocolFunctions, "getEntityTypes" | "createEntityTypes" | "updateEntityTypes" | "deleteEntityTypes">; | ||
functions: BlockProtocolFunctions; | ||
}; | ||
export declare const useMockDatastore: (initialData?: MockData) => MockDataStore; | ||
export {}; |
@@ -62,2 +62,3 @@ "use strict"; | ||
var uuid_1 = require("uuid"); | ||
var useDefaultArrayState_1 = require("./useDefaultArrayState"); | ||
var util_1 = require("./util"); | ||
@@ -68,20 +69,12 @@ var useMockDatastore = function (initialData) { | ||
links: [], | ||
linkedAggregationDefinitions: [], | ||
entityTypes: [], | ||
}; } | ||
var previousInitialEntitiesString = (0, react_1.useRef)(JSON.stringify(initialData.entities)); | ||
var _a = (0, react_1.useState)(initialData.entities), entities = _a[0], setEntities = _a[1]; | ||
var _b = (0, react_1.useState)(initialData.links), links = _b[0], setLinks = _b[1]; | ||
var _c = (0, react_1.useState)(initialData.entityTypes), entityTypes = _c[0], _setEntityTypes = _c[1]; | ||
(0, react_1.useEffect)(function () { | ||
var initialEntitiesString = JSON.stringify(initialData.entities); | ||
if (initialEntitiesString !== previousInitialEntitiesString.current) { | ||
setEntities(initialData.entities); | ||
previousInitialEntitiesString.current = initialEntitiesString; | ||
} | ||
}, [initialData.entities]); | ||
var aggregateEntityTypes = (0, react_1.useCallback)(function (payload) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, (0, util_1.filterAndSortEntitiesOrTypes)(entityTypes, payload)]; | ||
}); | ||
}); }, [entityTypes]); | ||
var _a = (0, useDefaultArrayState_1.useDefaultArrayState)(initialData.entities), entities = _a[0], setEntities = _a[1]; | ||
var _b = (0, useDefaultArrayState_1.useDefaultArrayState)(initialData.entityTypes), entityTypes = _b[0], setEntityTypes = _b[1]; | ||
var _c = (0, useDefaultArrayState_1.useDefaultArrayState)(initialData.links), links = _c[0], setLinks = _c[1]; | ||
var _d = (0, useDefaultArrayState_1.useDefaultArrayState)(initialData.linkedAggregationDefinitions), linkedAggregations = _d[0], setLinkedAggregations = _d[1]; | ||
var aggregateEntityTypes = (0, react_1.useCallback)(function (payload) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { | ||
return [2 /*return*/, (0, util_1.filterAndSortEntitiesOrTypes)(entityTypes, payload)]; | ||
}); }); }, [entityTypes]); | ||
var aggregateEntities = (0, react_1.useCallback)(function (payload) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { | ||
@@ -111,3 +104,3 @@ return [2 /*return*/, (0, util_1.filterAndSortEntitiesOrTypes)(entities, payload)]; | ||
}); | ||
}); }, []); | ||
}); }, [setEntities, setLinks]); | ||
var getEntities = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -117,6 +110,9 @@ return __generator(this, function (_a) { | ||
var foundEntity = entities.find(function (entity) { | ||
return (0, util_1.matchIdentifiers)(entity, action); | ||
return (0, util_1.matchEntityIdentifiers)({ | ||
entityToCheck: entity, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (!foundEntity) { | ||
throw new Error("Could not find entity with identifiers ".concat(JSON.stringify(action))); | ||
throw new Error("Could not find entity for getEntities action ".concat(JSON.stringify(action, undefined, 2))); | ||
} | ||
@@ -134,3 +130,6 @@ return foundEntity; | ||
var actionToApply = actions.find(function (action) { | ||
return (0, util_1.matchIdentifiers)(action, entity); | ||
return (0, util_1.matchEntityIdentifiers)({ | ||
entityToCheck: entity, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
@@ -147,21 +146,98 @@ if (actionToApply) { | ||
}); | ||
}); }, []); | ||
}); }, [setEntities]); | ||
var deleteEntities = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var operationStatus; | ||
return __generator(this, function (_a) { | ||
operationStatus = new Array(actions.length).fill(false); | ||
setEntities(function (currentEntities) { | ||
return currentEntities | ||
.map(function (entity) { | ||
var isMatch = actions.some(function (action) { | ||
return (0, util_1.matchIdentifiers)(entity, action); | ||
return currentEntities.filter(function (entity) { | ||
var deleteActionIndex = actions.findIndex(function (action) { | ||
return (0, util_1.matchEntityIdentifiers)({ | ||
entityToCheck: entity, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (isMatch) { | ||
return null; | ||
if (deleteActionIndex > -1) { | ||
operationStatus[deleteActionIndex] = true; | ||
return false; | ||
} | ||
return entity; | ||
}) | ||
.filter(function (entity) { return !!entity; }); | ||
return true; | ||
}); | ||
}); | ||
return [2 /*return*/, new Array(actions.length).fill(true)]; | ||
return [2 /*return*/, operationStatus]; | ||
}); | ||
}); }, []); | ||
}); }, [setEntities]); | ||
var createEntityTypes = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var newEntityTypes; | ||
return __generator(this, function (_a) { | ||
newEntityTypes = actions.map(function (action) { | ||
var entityTypeId = (0, uuid_1.v4)(); | ||
var accountId = action.accountId, schema = action.schema; | ||
return __assign({ accountId: accountId, entityTypeId: entityTypeId }, schema); // @todo fix this – make 'schema' a narrower object in BP types? | ||
}); | ||
setEntityTypes(function (currentEntityTypes) { return __spreadArray(__spreadArray([], currentEntityTypes, true), newEntityTypes, true); }); | ||
return [2 /*return*/, newEntityTypes]; | ||
}); | ||
}); }, [setEntityTypes]); | ||
var getEntityTypes = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, actions.map(function (action) { | ||
var foundEntityType = entityTypes.find(function (entityType) { | ||
return (0, util_1.matchEntityTypeIdentifiers)({ | ||
entityTypeToCheck: entityType, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (!foundEntityType) { | ||
throw new Error("Could not find entity type for getEntityTypes action ".concat(JSON.stringify(action))); | ||
} | ||
return foundEntityType; | ||
})]; | ||
}); | ||
}); }, [entityTypes]); | ||
var updateEntityTypes = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var updatedEntityTypes; | ||
return __generator(this, function (_a) { | ||
updatedEntityTypes = []; | ||
setEntityTypes(function (currentEntityTypes) { | ||
return currentEntityTypes.map(function (entityType) { | ||
var actionToApply = actions.find(function (action) { | ||
return (0, util_1.matchEntityTypeIdentifiers)({ | ||
entityTypeToCheck: entityType, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (actionToApply) { | ||
var newEntityType = __assign(__assign({}, actionToApply.schema), { accountId: entityType.accountId, entityTypeId: entityType.entityTypeId }); | ||
updatedEntityTypes.push(newEntityType); | ||
return newEntityType; | ||
} | ||
return entityType; | ||
}); | ||
}); | ||
return [2 /*return*/, updatedEntityTypes]; | ||
}); | ||
}); }, [setEntityTypes]); | ||
var deleteEntityTypes = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var operationStatus; | ||
return __generator(this, function (_a) { | ||
operationStatus = new Array(actions.length).fill(false); | ||
setEntityTypes(function (currentEntityTypes) { | ||
return currentEntityTypes.filter(function (entityType) { | ||
var deleteActionIndex = actions.findIndex(function (action) { | ||
return (0, util_1.matchEntityTypeIdentifiers)({ | ||
entityTypeToCheck: entityType, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (deleteActionIndex > -1) { | ||
operationStatus[deleteActionIndex] = true; | ||
return true; | ||
} | ||
return true; | ||
}); | ||
}); | ||
return [2 /*return*/, operationStatus]; | ||
}); | ||
}); }, [setEntityTypes]); | ||
var createLinks = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -174,3 +250,3 @@ var newLinks; | ||
}); | ||
}); }, []); | ||
}); }, [setLinks]); | ||
var getLinks = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -180,3 +256,7 @@ return __generator(this, function (_a) { | ||
var linkId = _a.linkId; | ||
return links.find(function (link) { return link.linkId === linkId; }); | ||
var foundLink = links.find(function (link) { return link.linkId === linkId; }); | ||
if (!foundLink) { | ||
throw new Error("link with linkId '".concat(linkId, "' not found.")); | ||
} | ||
return foundLink; | ||
})]; | ||
@@ -191,13 +271,5 @@ }); | ||
return currentLinks.map(function (link) { | ||
var actionToApply = actions.find(function (action) { | ||
if ("linkId" in action) { | ||
return link.linkId === action.linkId; | ||
} | ||
var sourceEntityId = action.sourceEntityId, sourceAccountId = action.sourceAccountId, path = action.path; | ||
return (sourceEntityId === link.sourceEntityId && | ||
path === link.path && | ||
(!sourceAccountId || sourceAccountId === link.sourceAccountId)); | ||
}); | ||
var actionToApply = actions.find(function (action) { return link.linkId === action.linkId; }); | ||
if (actionToApply) { | ||
var newLink = __assign(__assign({}, link), { operation: actionToApply.data }); | ||
var newLink = __assign(__assign({}, link), { index: actionToApply.data.index }); | ||
updatedLinks.push(newLink); | ||
@@ -211,3 +283,3 @@ return newLink; | ||
}); | ||
}); }, []); | ||
}); }, [setLinks]); | ||
var deleteLinks = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -228,3 +300,65 @@ return __generator(this, function (_a) { | ||
}); | ||
}); }, []); | ||
}); }, [setLinks]); | ||
var createLinkedAggregations = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var newLinkedAggregations; | ||
return __generator(this, function (_a) { | ||
newLinkedAggregations = actions.map(function (action) { return (__assign({ aggregationId: (0, uuid_1.v4)() }, action)); }); | ||
setLinkedAggregations(function (currentLinkedAggregations) { return __spreadArray(__spreadArray([], currentLinkedAggregations, true), newLinkedAggregations, true); }); | ||
return [2 /*return*/, newLinkedAggregations]; | ||
}); | ||
}); }, [setLinkedAggregations]); | ||
var getLinkedAggregations = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, actions.map(function (_a) { | ||
var aggregationId = _a.aggregationId; | ||
var foundLinkedAggregation = linkedAggregations.find(function (linkedAggregation) { | ||
return linkedAggregation.aggregationId === aggregationId; | ||
}); | ||
if (!foundLinkedAggregation) { | ||
throw new Error("LinkedAggregation with aggregationId '".concat(aggregationId, "' not found.")); | ||
} | ||
return __assign(__assign({}, foundLinkedAggregation), (0, util_1.filterAndSortEntitiesOrTypes)(entities, foundLinkedAggregation)); | ||
})]; | ||
}); | ||
}); }, [entities, linkedAggregations]); | ||
var updateLinkedAggregations = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var updatedLinkedAggregations; | ||
return __generator(this, function (_a) { | ||
updatedLinkedAggregations = []; | ||
setLinkedAggregations(function (currentLinkedAggregations) { | ||
return currentLinkedAggregations.map(function (linkedAggregation) { | ||
var actionToApply = actions.find(function (action) { | ||
return linkedAggregation.aggregationId === action.aggregationId; | ||
}); | ||
if (actionToApply) { | ||
var newLinkedAggregation = __assign(__assign({}, linkedAggregation), { operation: actionToApply.operation }); | ||
updatedLinkedAggregations.push(newLinkedAggregation); | ||
return newLinkedAggregation; | ||
} | ||
return linkedAggregation; | ||
}); | ||
}); | ||
return [2 /*return*/, updatedLinkedAggregations]; | ||
}); | ||
}); }, [setLinkedAggregations]); | ||
var deleteLinkedAggregations = (0, react_1.useCallback)(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
setLinkedAggregations(function (currentLinkedAggregations) { | ||
return currentLinkedAggregations | ||
.map(function (linkedAggregation) { | ||
var isMatch = actions.some(function (action) { | ||
return action.aggregationId === linkedAggregation.aggregationId; | ||
}); | ||
if (isMatch) { | ||
return null; | ||
} | ||
return linkedAggregation; | ||
}) | ||
.filter(function (linkedAggregation) { | ||
return !!linkedAggregation; | ||
}); | ||
}); | ||
return [2 /*return*/, new Array(actions.length).fill(true)]; | ||
}); | ||
}); }, [setLinkedAggregations]); | ||
var uploadFile = (0, react_1.useCallback)(function (_a) { | ||
@@ -298,2 +432,6 @@ var accountId = _a.accountId, file = _a.file, url = _a.url, mediaType = _a.mediaType; | ||
updateEntities: updateEntities, | ||
getEntityTypes: getEntityTypes, | ||
createEntityTypes: createEntityTypes, | ||
deleteEntityTypes: deleteEntityTypes, | ||
updateEntityTypes: updateEntityTypes, | ||
getLinks: getLinks, | ||
@@ -303,5 +441,10 @@ createLinks: createLinks, | ||
updateLinks: updateLinks, | ||
getLinkedAggregations: getLinkedAggregations, | ||
createLinkedAggregations: createLinkedAggregations, | ||
deleteLinkedAggregations: deleteLinkedAggregations, | ||
updateLinkedAggregations: updateLinkedAggregations, | ||
uploadFile: uploadFile, | ||
}, | ||
links: links, | ||
linkedAggregationDefinitions: linkedAggregations, | ||
}; | ||
@@ -308,0 +451,0 @@ }; |
import { BlockProtocolAggregateEntitiesFunction, BlockProtocolAggregateEntitiesPayload, BlockProtocolAggregateEntityTypesFunction, BlockProtocolAggregateEntityTypesPayload, BlockProtocolEntity, BlockProtocolEntityType } from "blockprotocol"; | ||
declare type Identifiers = { | ||
declare type EntityIdentifiers = { | ||
accountId?: string | null; | ||
@@ -7,3 +7,14 @@ entityId: string; | ||
}; | ||
export declare const matchIdentifiers: (first: Identifiers, second: Identifiers) => boolean; | ||
export declare const matchEntityIdentifiers: ({ providedIdentifiers, entityToCheck, }: { | ||
providedIdentifiers: EntityIdentifiers; | ||
entityToCheck: EntityIdentifiers; | ||
}) => boolean; | ||
declare type EntityTypeIdentifiers = { | ||
accountId?: string | null; | ||
entityTypeId: string | null; | ||
}; | ||
export declare const matchEntityTypeIdentifiers: ({ providedIdentifiers, entityTypeToCheck, }: { | ||
providedIdentifiers: EntityTypeIdentifiers; | ||
entityTypeToCheck: EntityTypeIdentifiers; | ||
}) => boolean; | ||
declare type Unpromise<T extends Promise<any>> = T extends Promise<infer U> ? U : never; | ||
@@ -10,0 +21,0 @@ export declare function filterAndSortEntitiesOrTypes(entities: BlockProtocolEntity[], payload: BlockProtocolAggregateEntitiesPayload): Unpromise<ReturnType<BlockProtocolAggregateEntitiesFunction>>; |
@@ -23,13 +23,15 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.filterAndSortEntitiesOrTypes = exports.matchIdentifiers = void 0; | ||
exports.filterAndSortEntitiesOrTypes = exports.matchEntityTypeIdentifiers = exports.matchEntityIdentifiers = void 0; | ||
var lodash_1 = require("lodash"); | ||
var matchIdentifiers = function (first, second) { | ||
if (first.entityId !== second.entityId) { | ||
var matchEntityIdentifiers = function (_a) { | ||
var providedIdentifiers = _a.providedIdentifiers, entityToCheck = _a.entityToCheck; | ||
if (providedIdentifiers.entityId !== entityToCheck.entityId) { | ||
return false; | ||
} | ||
if (first.accountId != null && first.accountId !== second.accountId) { | ||
if (providedIdentifiers.accountId != null && | ||
providedIdentifiers.accountId !== entityToCheck.accountId) { | ||
return false; | ||
} | ||
if (first.entityTypeId != null && | ||
first.entityTypeId !== second.entityTypeId) { | ||
if (providedIdentifiers.entityTypeId != null && | ||
providedIdentifiers.entityTypeId !== entityToCheck.entityTypeId) { | ||
return false; | ||
@@ -39,3 +41,15 @@ } | ||
}; | ||
exports.matchIdentifiers = matchIdentifiers; | ||
exports.matchEntityIdentifiers = matchEntityIdentifiers; | ||
var matchEntityTypeIdentifiers = function (_a) { | ||
var providedIdentifiers = _a.providedIdentifiers, entityTypeToCheck = _a.entityTypeToCheck; | ||
if (providedIdentifiers.entityTypeId !== entityTypeToCheck.entityTypeId) { | ||
return false; | ||
} | ||
if (providedIdentifiers.accountId != null && | ||
providedIdentifiers.accountId !== entityTypeToCheck.accountId) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
exports.matchEntityTypeIdentifiers = matchEntityTypeIdentifiers; | ||
var filterEntities = function (params) { | ||
@@ -54,3 +68,2 @@ var entityTypeId = params.entityTypeId, entityTypeVersionId = params.entityTypeVersionId, entities = params.entities, multiFilter = params.multiFilter; | ||
var item = (0, lodash_1.get)(entity, filterItem.field); | ||
// @todo support non-string comparison | ||
if (typeof item !== "string") { | ||
@@ -92,3 +105,5 @@ return null; | ||
var field = _a.field; | ||
return field; | ||
return function (entity) { | ||
return (0, lodash_1.get)(entity, field); | ||
}; | ||
}), multiSort.map(function (_a) { | ||
@@ -95,0 +110,0 @@ var desc = _a.desc; |
import { entities } from "./entities"; | ||
import { entityTypes } from "./entityTypes"; | ||
import { linkedAggregationDefinitions } from "./linkedAggregationDefinitions"; | ||
import { links } from "./links"; | ||
@@ -8,3 +9,4 @@ export var mockData = { | ||
links: links, | ||
linkedAggregationDefinitions: linkedAggregationDefinitions, | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -0,3 +1,3 @@ | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolLink, BlockProtocolLinkedAggregationDefinition } from "blockprotocol"; | ||
import { ReactElement, VoidFunctionComponent } from "react"; | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolLink } from "blockprotocol"; | ||
declare type MockBlockDockProps = { | ||
@@ -9,4 +9,16 @@ children: ReactElement; | ||
initialLinks?: BlockProtocolLink[]; | ||
initialLinkedAggregations?: BlockProtocolLinkedAggregationDefinition[]; | ||
}; | ||
/** | ||
* A component to wrap a Block Protocol block, acting as a mock embedding application. | ||
* It provides the functions specified in the Block Protocol, and mock data which can be customized via props. | ||
* See README.md for usage instructions. | ||
* @param children the block component to be provided mock data and functions, with any starting props | ||
* @param [blockSchema] - The schema for the block entity | ||
* @param [initialEntities] - The entities to include in the data store (NOT the block entity, which is always provided) | ||
* @param [initialEntityTypes] - The entity types to include in the data store (NOT the block's type, which is always provided) | ||
* @param [initialLinks] - The links to include in the data store | ||
* @param [initialLinkedAggregations] - The linkedAggregation DEFINITIONS to include in the data store (results will be resolved automatically) | ||
*/ | ||
export declare const MockBlockDock: VoidFunctionComponent<MockBlockDockProps>; | ||
export {}; |
@@ -13,11 +13,21 @@ var __assign = (this && this.__assign) || function () { | ||
import { Children, cloneElement, useEffect, useMemo, useRef, } from "react"; | ||
import { useMockDatastore } from "./useMockDatastore"; | ||
import { mockData as initialMockData } from "./data"; | ||
import { useLinkFields } from "./useLinkFields"; | ||
import { useMockDatastore } from "./useMockDatastore"; | ||
/** | ||
* A component to wrap a Block Protocol block, acting as a mock embedding application. | ||
* It provides the functions specified in the Block Protocol, and mock data which can be customized via props. | ||
* See README.md for usage instructions. | ||
* @param children the block component to be provided mock data and functions, with any starting props | ||
* @param [blockSchema] - The schema for the block entity | ||
* @param [initialEntities] - The entities to include in the data store (NOT the block entity, which is always provided) | ||
* @param [initialEntityTypes] - The entity types to include in the data store (NOT the block's type, which is always provided) | ||
* @param [initialLinks] - The links to include in the data store | ||
* @param [initialLinkedAggregations] - The linkedAggregation DEFINITIONS to include in the data store (results will be resolved automatically) | ||
*/ | ||
export var MockBlockDock = function (_a) { | ||
var children = _a.children, blockSchema = _a.blockSchema, initialEntities = _a.initialEntities, initialEntityTypes = _a.initialEntityTypes, initialLinks = _a.initialLinks; | ||
var children = _a.children, blockSchema = _a.blockSchema, initialEntities = _a.initialEntities, initialEntityTypes = _a.initialEntityTypes, initialLinks = _a.initialLinks, initialLinkedAggregations = _a.initialLinkedAggregations; | ||
var mockData = useMemo(function () { | ||
var _a; | ||
var blockEntityType = __assign({ entityTypeId: "blockType1", title: "BlockType", type: "object", $schema: "https://json-schema.org/draft/2019-09/schema", $id: "http://localhost/blockType1" }, (blockSchema !== null && blockSchema !== void 0 ? blockSchema : {})); | ||
var accountId = (_a = children.props.accountId) !== null && _a !== void 0 ? _a : "accountId"; | ||
var accountId = children.props.accountId; | ||
var initialBlockEntity = { | ||
@@ -39,2 +49,3 @@ accountId: accountId, | ||
links: initialLinks !== null && initialLinks !== void 0 ? initialLinks : initialMockData.links, | ||
linkedAggregationDefinitions: initialLinkedAggregations !== null && initialLinkedAggregations !== void 0 ? initialLinkedAggregations : initialMockData.linkedAggregationDefinitions, | ||
}; | ||
@@ -49,8 +60,11 @@ nextMockData.entities.push(initialBlockEntity); | ||
initialLinks, | ||
initialLinkedAggregations, | ||
children.props, | ||
]); | ||
var _b = useMockDatastore(mockData), entities = _b.entities, entityTypes = _b.entityTypes, links = _b.links, functions = _b.functions; | ||
var _b = useMockDatastore(mockData), entities = _b.entities, entityTypes = _b.entityTypes, links = _b.links, linkedAggregationDefinitions = _b.linkedAggregationDefinitions, functions = _b.functions; | ||
var latestBlockEntity = useMemo(function () { | ||
var _a; | ||
return ((_a = entities.find(function (entity) { return entity.entityId === children.props.entityId; })) !== null && _a !== void 0 ? _a : mockData.entities.find(function (entity) { return entity.entityId === children.props.entityId; })); | ||
return ((_a = entities.find(function (entity) { return entity.entityId === children.props.entityId; })) !== null && _a !== void 0 ? _a : | ||
// fallback in case the entityId of the wrapped component is updated by updating its props | ||
mockData.entities.find(function (entity) { return entity.entityId === children.props.entityId; })); | ||
}, [entities, children.props.entityId, mockData.entities]); | ||
@@ -62,2 +76,3 @@ if (!latestBlockEntity) { | ||
var updateEntities = functions.updateEntities; | ||
// watch for changes to the props provided to the wrapped component, and update the associated entity if they change | ||
var prevChildPropsString = useRef(JSON.stringify(children.props)); | ||
@@ -72,7 +87,10 @@ useEffect(function () { | ||
}, [accountId, entityId, entityTypeId, children.props, updateEntities]); | ||
// construct BP-specified link fields from the links and linkedAggregations in the datastore | ||
var _c = useLinkFields({ | ||
entities: entities, | ||
links: links, | ||
linkedAggregationDefinitions: linkedAggregationDefinitions, | ||
startingEntity: latestBlockEntity, | ||
}), linkedAggregations = _c.linkedAggregations, linkedEntities = _c.linkedEntities, linkGroups = _c.linkGroups; | ||
// @todo we don't do anything with this type except check it exists - do we need to do this? | ||
var latestBlockEntityType = useMemo(function () { | ||
@@ -79,0 +97,0 @@ return entityTypes.find(function (entityType) { |
@@ -1,2 +0,2 @@ | ||
import { BlockProtocolEntity, BlockProtocolLink, BlockProtocolLinkGroup, BlockProtocolProps } from "blockprotocol"; | ||
import { BlockProtocolEntity, BlockProtocolLink, BlockProtocolLinkedAggregationDefinition, BlockProtocolLinkGroup, BlockProtocolProps } from "blockprotocol"; | ||
declare type LinkFields = { | ||
@@ -7,8 +7,9 @@ linkedAggregations: BlockProtocolProps["linkedAggregations"]; | ||
}; | ||
export declare const useLinkFields: ({ entities, links, startingEntity, }: { | ||
export declare const useLinkFields: ({ entities, links, linkedAggregationDefinitions, startingEntity, }: { | ||
depth?: number | undefined; | ||
entities: BlockProtocolEntity[]; | ||
links: BlockProtocolLink[]; | ||
linkedAggregationDefinitions: BlockProtocolLinkedAggregationDefinition[]; | ||
startingEntity: BlockProtocolEntity; | ||
}) => LinkFields; | ||
export {}; |
@@ -13,5 +13,5 @@ var __assign = (this && this.__assign) || function () { | ||
import { useMemo } from "react"; | ||
import { filterAndSortEntitiesOrTypes, matchIdentifiers } from "./util"; | ||
import { filterAndSortEntitiesOrTypes, matchEntityIdentifiers } from "./util"; | ||
export var useLinkFields = function (_a) { | ||
var entities = _a.entities, links = _a.links, startingEntity = _a.startingEntity; | ||
var entities = _a.entities, links = _a.links, linkedAggregationDefinitions = _a.linkedAggregationDefinitions, startingEntity = _a.startingEntity; | ||
// @todo optionally resolve to further depth, i.e. follow links from linked entities | ||
@@ -21,26 +21,24 @@ var _b = useMemo(function () { | ||
var sourceAccountId = _a.sourceAccountId, sourceEntityId = _a.sourceEntityId, sourceEntityTypeId = _a.sourceEntityTypeId; | ||
return matchIdentifiers({ | ||
accountId: sourceAccountId, | ||
entityId: sourceEntityId, | ||
entityTypeId: sourceEntityTypeId, | ||
}, startingEntity); | ||
return matchEntityIdentifiers({ | ||
providedIdentifiers: { | ||
accountId: sourceAccountId, | ||
entityId: sourceEntityId, | ||
entityTypeId: sourceEntityTypeId, | ||
}, | ||
entityToCheck: startingEntity, | ||
}); | ||
}); | ||
var calculatedLinkGroups = linksFromStartingEntity.reduce(function (linkGroupsAcc, link) { | ||
if ("operation" in link) { | ||
/** | ||
* this is an aggregation link - they don't go in linkGroups, | ||
* because they are in linkedAggregations | ||
* @todo should they be in linkGroups too? | ||
* */ | ||
return linkGroupsAcc; | ||
} | ||
var existingGroup = linkGroupsAcc.find(function (group) { | ||
return matchIdentifiers({ | ||
accountId: link.sourceAccountId, | ||
entityId: link.sourceEntityId, | ||
entityTypeId: link.sourceEntityTypeId, | ||
}, { | ||
accountId: group.sourceAccountId, | ||
entityId: group.sourceEntityId, | ||
entityTypeId: group.sourceEntityTypeId, | ||
return matchEntityIdentifiers({ | ||
providedIdentifiers: { | ||
accountId: link.sourceAccountId, | ||
entityId: link.sourceEntityId, | ||
entityTypeId: link.sourceEntityTypeId, | ||
}, | ||
entityToCheck: { | ||
accountId: group.sourceAccountId, | ||
entityId: group.sourceEntityId, | ||
entityTypeId: group.sourceEntityTypeId, | ||
}, | ||
}) && link.path === group.path; | ||
@@ -64,29 +62,37 @@ }); | ||
return linksFromStartingEntity.find(function (link) { | ||
return "destinationEntityId" in link && | ||
matchIdentifiers({ | ||
return matchEntityIdentifiers({ | ||
providedIdentifiers: { | ||
accountId: link.destinationAccountId, | ||
entityId: link.destinationEntityId, | ||
entityTypeId: link.destinationEntityTypeId, | ||
}, entity); | ||
}, | ||
entityToCheck: entity, | ||
}); | ||
}); | ||
}); | ||
var calculatedLinkedAggregations = linksFromStartingEntity | ||
.map(function (link) { | ||
if (!("operation" in link)) { | ||
var calculatedLinkedAggregations = linkedAggregationDefinitions | ||
.map(function (linkedAggregation) { | ||
var isLinkedFromStartingEntity = matchEntityIdentifiers({ | ||
providedIdentifiers: { | ||
accountId: linkedAggregation.sourceAccountId, | ||
entityId: linkedAggregation.sourceEntityId, | ||
entityTypeId: linkedAggregation.sourceEntityTypeId, | ||
}, | ||
entityToCheck: startingEntity, | ||
}); | ||
if (!isLinkedFromStartingEntity) { | ||
return null; | ||
} | ||
var results = filterAndSortEntitiesOrTypes(entities, { | ||
operation: link.operation, | ||
}); | ||
return __assign(__assign({}, link), results); | ||
var results = filterAndSortEntitiesOrTypes(entities, linkedAggregation); | ||
return __assign(__assign({}, linkedAggregation), results); | ||
}) | ||
.filter(function (thing) { return thing !== null; }); | ||
return { | ||
linkedAggregations: calculatedLinkedAggregations, | ||
resolvedLinkedAggregations: calculatedLinkedAggregations, | ||
linkedEntities: calculatedLinkedEntities, | ||
linkGroups: calculatedLinkGroups, | ||
}; | ||
}, [entities, links, startingEntity]), linkedAggregations = _b.linkedAggregations, linkedEntities = _b.linkedEntities, linkGroups = _b.linkGroups; | ||
}, [entities, links, linkedAggregationDefinitions, startingEntity]), resolvedLinkedAggregations = _b.resolvedLinkedAggregations, linkedEntities = _b.linkedEntities, linkGroups = _b.linkGroups; | ||
return { | ||
linkedAggregations: linkedAggregations, | ||
linkedAggregations: resolvedLinkedAggregations, | ||
linkGroups: linkGroups, | ||
@@ -93,0 +99,0 @@ linkedEntities: linkedEntities, |
@@ -1,11 +0,12 @@ | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolFunctions, BlockProtocolLink } from "blockprotocol"; | ||
import { BlockProtocolEntity, BlockProtocolEntityType, BlockProtocolFunctions, BlockProtocolLink, BlockProtocolLinkedAggregationDefinition } from "blockprotocol"; | ||
export declare type MockData = { | ||
entities: BlockProtocolEntity[]; | ||
links: BlockProtocolLink[]; | ||
linkedAggregationDefinitions: BlockProtocolLinkedAggregationDefinition[]; | ||
entityTypes: BlockProtocolEntityType[]; | ||
}; | ||
declare type MockDataStore = MockData & { | ||
functions: Omit<BlockProtocolFunctions, "getEntityTypes" | "createEntityTypes" | "updateEntityTypes" | "deleteEntityTypes">; | ||
functions: BlockProtocolFunctions; | ||
}; | ||
export declare const useMockDatastore: (initialData?: MockData) => MockDataStore; | ||
export {}; |
@@ -57,5 +57,6 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
import { useCallback, useEffect, useRef, useState } from "react"; | ||
import { useCallback } from "react"; | ||
import { v4 as uuid } from "uuid"; | ||
import { filterAndSortEntitiesOrTypes, matchIdentifiers } from "./util"; | ||
import { useDefaultArrayState } from "./useDefaultArrayState"; | ||
import { filterAndSortEntitiesOrTypes, matchEntityIdentifiers, matchEntityTypeIdentifiers, } from "./util"; | ||
export var useMockDatastore = function (initialData) { | ||
@@ -65,20 +66,12 @@ if (initialData === void 0) { initialData = { | ||
links: [], | ||
linkedAggregationDefinitions: [], | ||
entityTypes: [], | ||
}; } | ||
var previousInitialEntitiesString = useRef(JSON.stringify(initialData.entities)); | ||
var _a = useState(initialData.entities), entities = _a[0], setEntities = _a[1]; | ||
var _b = useState(initialData.links), links = _b[0], setLinks = _b[1]; | ||
var _c = useState(initialData.entityTypes), entityTypes = _c[0], _setEntityTypes = _c[1]; | ||
useEffect(function () { | ||
var initialEntitiesString = JSON.stringify(initialData.entities); | ||
if (initialEntitiesString !== previousInitialEntitiesString.current) { | ||
setEntities(initialData.entities); | ||
previousInitialEntitiesString.current = initialEntitiesString; | ||
} | ||
}, [initialData.entities]); | ||
var aggregateEntityTypes = useCallback(function (payload) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, filterAndSortEntitiesOrTypes(entityTypes, payload)]; | ||
}); | ||
}); }, [entityTypes]); | ||
var _a = useDefaultArrayState(initialData.entities), entities = _a[0], setEntities = _a[1]; | ||
var _b = useDefaultArrayState(initialData.entityTypes), entityTypes = _b[0], setEntityTypes = _b[1]; | ||
var _c = useDefaultArrayState(initialData.links), links = _c[0], setLinks = _c[1]; | ||
var _d = useDefaultArrayState(initialData.linkedAggregationDefinitions), linkedAggregations = _d[0], setLinkedAggregations = _d[1]; | ||
var aggregateEntityTypes = useCallback(function (payload) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { | ||
return [2 /*return*/, filterAndSortEntitiesOrTypes(entityTypes, payload)]; | ||
}); }); }, [entityTypes]); | ||
var aggregateEntities = useCallback(function (payload) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { | ||
@@ -108,3 +101,3 @@ return [2 /*return*/, filterAndSortEntitiesOrTypes(entities, payload)]; | ||
}); | ||
}); }, []); | ||
}); }, [setEntities, setLinks]); | ||
var getEntities = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -114,6 +107,9 @@ return __generator(this, function (_a) { | ||
var foundEntity = entities.find(function (entity) { | ||
return matchIdentifiers(entity, action); | ||
return matchEntityIdentifiers({ | ||
entityToCheck: entity, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (!foundEntity) { | ||
throw new Error("Could not find entity with identifiers ".concat(JSON.stringify(action))); | ||
throw new Error("Could not find entity for getEntities action ".concat(JSON.stringify(action, undefined, 2))); | ||
} | ||
@@ -131,3 +127,6 @@ return foundEntity; | ||
var actionToApply = actions.find(function (action) { | ||
return matchIdentifiers(action, entity); | ||
return matchEntityIdentifiers({ | ||
entityToCheck: entity, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
@@ -144,21 +143,98 @@ if (actionToApply) { | ||
}); | ||
}); }, []); | ||
}); }, [setEntities]); | ||
var deleteEntities = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var operationStatus; | ||
return __generator(this, function (_a) { | ||
operationStatus = new Array(actions.length).fill(false); | ||
setEntities(function (currentEntities) { | ||
return currentEntities | ||
.map(function (entity) { | ||
var isMatch = actions.some(function (action) { | ||
return matchIdentifiers(entity, action); | ||
return currentEntities.filter(function (entity) { | ||
var deleteActionIndex = actions.findIndex(function (action) { | ||
return matchEntityIdentifiers({ | ||
entityToCheck: entity, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (isMatch) { | ||
return null; | ||
if (deleteActionIndex > -1) { | ||
operationStatus[deleteActionIndex] = true; | ||
return false; | ||
} | ||
return entity; | ||
}) | ||
.filter(function (entity) { return !!entity; }); | ||
return true; | ||
}); | ||
}); | ||
return [2 /*return*/, new Array(actions.length).fill(true)]; | ||
return [2 /*return*/, operationStatus]; | ||
}); | ||
}); }, []); | ||
}); }, [setEntities]); | ||
var createEntityTypes = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var newEntityTypes; | ||
return __generator(this, function (_a) { | ||
newEntityTypes = actions.map(function (action) { | ||
var entityTypeId = uuid(); | ||
var accountId = action.accountId, schema = action.schema; | ||
return __assign({ accountId: accountId, entityTypeId: entityTypeId }, schema); // @todo fix this – make 'schema' a narrower object in BP types? | ||
}); | ||
setEntityTypes(function (currentEntityTypes) { return __spreadArray(__spreadArray([], currentEntityTypes, true), newEntityTypes, true); }); | ||
return [2 /*return*/, newEntityTypes]; | ||
}); | ||
}); }, [setEntityTypes]); | ||
var getEntityTypes = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, actions.map(function (action) { | ||
var foundEntityType = entityTypes.find(function (entityType) { | ||
return matchEntityTypeIdentifiers({ | ||
entityTypeToCheck: entityType, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (!foundEntityType) { | ||
throw new Error("Could not find entity type for getEntityTypes action ".concat(JSON.stringify(action))); | ||
} | ||
return foundEntityType; | ||
})]; | ||
}); | ||
}); }, [entityTypes]); | ||
var updateEntityTypes = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var updatedEntityTypes; | ||
return __generator(this, function (_a) { | ||
updatedEntityTypes = []; | ||
setEntityTypes(function (currentEntityTypes) { | ||
return currentEntityTypes.map(function (entityType) { | ||
var actionToApply = actions.find(function (action) { | ||
return matchEntityTypeIdentifiers({ | ||
entityTypeToCheck: entityType, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (actionToApply) { | ||
var newEntityType = __assign(__assign({}, actionToApply.schema), { accountId: entityType.accountId, entityTypeId: entityType.entityTypeId }); | ||
updatedEntityTypes.push(newEntityType); | ||
return newEntityType; | ||
} | ||
return entityType; | ||
}); | ||
}); | ||
return [2 /*return*/, updatedEntityTypes]; | ||
}); | ||
}); }, [setEntityTypes]); | ||
var deleteEntityTypes = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var operationStatus; | ||
return __generator(this, function (_a) { | ||
operationStatus = new Array(actions.length).fill(false); | ||
setEntityTypes(function (currentEntityTypes) { | ||
return currentEntityTypes.filter(function (entityType) { | ||
var deleteActionIndex = actions.findIndex(function (action) { | ||
return matchEntityTypeIdentifiers({ | ||
entityTypeToCheck: entityType, | ||
providedIdentifiers: action, | ||
}); | ||
}); | ||
if (deleteActionIndex > -1) { | ||
operationStatus[deleteActionIndex] = true; | ||
return true; | ||
} | ||
return true; | ||
}); | ||
}); | ||
return [2 /*return*/, operationStatus]; | ||
}); | ||
}); }, [setEntityTypes]); | ||
var createLinks = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -171,3 +247,3 @@ var newLinks; | ||
}); | ||
}); }, []); | ||
}); }, [setLinks]); | ||
var getLinks = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -177,3 +253,7 @@ return __generator(this, function (_a) { | ||
var linkId = _a.linkId; | ||
return links.find(function (link) { return link.linkId === linkId; }); | ||
var foundLink = links.find(function (link) { return link.linkId === linkId; }); | ||
if (!foundLink) { | ||
throw new Error("link with linkId '".concat(linkId, "' not found.")); | ||
} | ||
return foundLink; | ||
})]; | ||
@@ -188,13 +268,5 @@ }); | ||
return currentLinks.map(function (link) { | ||
var actionToApply = actions.find(function (action) { | ||
if ("linkId" in action) { | ||
return link.linkId === action.linkId; | ||
} | ||
var sourceEntityId = action.sourceEntityId, sourceAccountId = action.sourceAccountId, path = action.path; | ||
return (sourceEntityId === link.sourceEntityId && | ||
path === link.path && | ||
(!sourceAccountId || sourceAccountId === link.sourceAccountId)); | ||
}); | ||
var actionToApply = actions.find(function (action) { return link.linkId === action.linkId; }); | ||
if (actionToApply) { | ||
var newLink = __assign(__assign({}, link), { operation: actionToApply.data }); | ||
var newLink = __assign(__assign({}, link), { index: actionToApply.data.index }); | ||
updatedLinks.push(newLink); | ||
@@ -208,3 +280,3 @@ return newLink; | ||
}); | ||
}); }, []); | ||
}); }, [setLinks]); | ||
var deleteLinks = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
@@ -225,3 +297,65 @@ return __generator(this, function (_a) { | ||
}); | ||
}); }, []); | ||
}); }, [setLinks]); | ||
var createLinkedAggregations = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var newLinkedAggregations; | ||
return __generator(this, function (_a) { | ||
newLinkedAggregations = actions.map(function (action) { return (__assign({ aggregationId: uuid() }, action)); }); | ||
setLinkedAggregations(function (currentLinkedAggregations) { return __spreadArray(__spreadArray([], currentLinkedAggregations, true), newLinkedAggregations, true); }); | ||
return [2 /*return*/, newLinkedAggregations]; | ||
}); | ||
}); }, [setLinkedAggregations]); | ||
var getLinkedAggregations = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, actions.map(function (_a) { | ||
var aggregationId = _a.aggregationId; | ||
var foundLinkedAggregation = linkedAggregations.find(function (linkedAggregation) { | ||
return linkedAggregation.aggregationId === aggregationId; | ||
}); | ||
if (!foundLinkedAggregation) { | ||
throw new Error("LinkedAggregation with aggregationId '".concat(aggregationId, "' not found.")); | ||
} | ||
return __assign(__assign({}, foundLinkedAggregation), filterAndSortEntitiesOrTypes(entities, foundLinkedAggregation)); | ||
})]; | ||
}); | ||
}); }, [entities, linkedAggregations]); | ||
var updateLinkedAggregations = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
var updatedLinkedAggregations; | ||
return __generator(this, function (_a) { | ||
updatedLinkedAggregations = []; | ||
setLinkedAggregations(function (currentLinkedAggregations) { | ||
return currentLinkedAggregations.map(function (linkedAggregation) { | ||
var actionToApply = actions.find(function (action) { | ||
return linkedAggregation.aggregationId === action.aggregationId; | ||
}); | ||
if (actionToApply) { | ||
var newLinkedAggregation = __assign(__assign({}, linkedAggregation), { operation: actionToApply.operation }); | ||
updatedLinkedAggregations.push(newLinkedAggregation); | ||
return newLinkedAggregation; | ||
} | ||
return linkedAggregation; | ||
}); | ||
}); | ||
return [2 /*return*/, updatedLinkedAggregations]; | ||
}); | ||
}); }, [setLinkedAggregations]); | ||
var deleteLinkedAggregations = useCallback(function (actions) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
setLinkedAggregations(function (currentLinkedAggregations) { | ||
return currentLinkedAggregations | ||
.map(function (linkedAggregation) { | ||
var isMatch = actions.some(function (action) { | ||
return action.aggregationId === linkedAggregation.aggregationId; | ||
}); | ||
if (isMatch) { | ||
return null; | ||
} | ||
return linkedAggregation; | ||
}) | ||
.filter(function (linkedAggregation) { | ||
return !!linkedAggregation; | ||
}); | ||
}); | ||
return [2 /*return*/, new Array(actions.length).fill(true)]; | ||
}); | ||
}); }, [setLinkedAggregations]); | ||
var uploadFile = useCallback(function (_a) { | ||
@@ -295,2 +429,6 @@ var accountId = _a.accountId, file = _a.file, url = _a.url, mediaType = _a.mediaType; | ||
updateEntities: updateEntities, | ||
getEntityTypes: getEntityTypes, | ||
createEntityTypes: createEntityTypes, | ||
deleteEntityTypes: deleteEntityTypes, | ||
updateEntityTypes: updateEntityTypes, | ||
getLinks: getLinks, | ||
@@ -300,7 +438,12 @@ createLinks: createLinks, | ||
updateLinks: updateLinks, | ||
getLinkedAggregations: getLinkedAggregations, | ||
createLinkedAggregations: createLinkedAggregations, | ||
deleteLinkedAggregations: deleteLinkedAggregations, | ||
updateLinkedAggregations: updateLinkedAggregations, | ||
uploadFile: uploadFile, | ||
}, | ||
links: links, | ||
linkedAggregationDefinitions: linkedAggregations, | ||
}; | ||
}; | ||
//# sourceMappingURL=useMockDatastore.js.map |
import { BlockProtocolAggregateEntitiesFunction, BlockProtocolAggregateEntitiesPayload, BlockProtocolAggregateEntityTypesFunction, BlockProtocolAggregateEntityTypesPayload, BlockProtocolEntity, BlockProtocolEntityType } from "blockprotocol"; | ||
declare type Identifiers = { | ||
declare type EntityIdentifiers = { | ||
accountId?: string | null; | ||
@@ -7,3 +7,14 @@ entityId: string; | ||
}; | ||
export declare const matchIdentifiers: (first: Identifiers, second: Identifiers) => boolean; | ||
export declare const matchEntityIdentifiers: ({ providedIdentifiers, entityToCheck, }: { | ||
providedIdentifiers: EntityIdentifiers; | ||
entityToCheck: EntityIdentifiers; | ||
}) => boolean; | ||
declare type EntityTypeIdentifiers = { | ||
accountId?: string | null; | ||
entityTypeId: string | null; | ||
}; | ||
export declare const matchEntityTypeIdentifiers: ({ providedIdentifiers, entityTypeToCheck, }: { | ||
providedIdentifiers: EntityTypeIdentifiers; | ||
entityTypeToCheck: EntityTypeIdentifiers; | ||
}) => boolean; | ||
declare type Unpromise<T extends Promise<any>> = T extends Promise<infer U> ? U : never; | ||
@@ -10,0 +21,0 @@ export declare function filterAndSortEntitiesOrTypes(entities: BlockProtocolEntity[], payload: BlockProtocolAggregateEntitiesPayload): Unpromise<ReturnType<BlockProtocolAggregateEntitiesFunction>>; |
@@ -22,11 +22,13 @@ var __assign = (this && this.__assign) || function () { | ||
import { get, orderBy } from "lodash"; | ||
export var matchIdentifiers = function (first, second) { | ||
if (first.entityId !== second.entityId) { | ||
export var matchEntityIdentifiers = function (_a) { | ||
var providedIdentifiers = _a.providedIdentifiers, entityToCheck = _a.entityToCheck; | ||
if (providedIdentifiers.entityId !== entityToCheck.entityId) { | ||
return false; | ||
} | ||
if (first.accountId != null && first.accountId !== second.accountId) { | ||
if (providedIdentifiers.accountId != null && | ||
providedIdentifiers.accountId !== entityToCheck.accountId) { | ||
return false; | ||
} | ||
if (first.entityTypeId != null && | ||
first.entityTypeId !== second.entityTypeId) { | ||
if (providedIdentifiers.entityTypeId != null && | ||
providedIdentifiers.entityTypeId !== entityToCheck.entityTypeId) { | ||
return false; | ||
@@ -36,2 +38,13 @@ } | ||
}; | ||
export var matchEntityTypeIdentifiers = function (_a) { | ||
var providedIdentifiers = _a.providedIdentifiers, entityTypeToCheck = _a.entityTypeToCheck; | ||
if (providedIdentifiers.entityTypeId !== entityTypeToCheck.entityTypeId) { | ||
return false; | ||
} | ||
if (providedIdentifiers.accountId != null && | ||
providedIdentifiers.accountId !== entityTypeToCheck.accountId) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
var filterEntities = function (params) { | ||
@@ -50,3 +63,2 @@ var entityTypeId = params.entityTypeId, entityTypeVersionId = params.entityTypeVersionId, entities = params.entities, multiFilter = params.multiFilter; | ||
var item = get(entity, filterItem.field); | ||
// @todo support non-string comparison | ||
if (typeof item !== "string") { | ||
@@ -88,3 +100,5 @@ return null; | ||
var field = _a.field; | ||
return field; | ||
return function (entity) { | ||
return get(entity, field); | ||
}; | ||
}), multiSort.map(function (_a) { | ||
@@ -91,0 +105,0 @@ var desc = _a.desc; |
{ | ||
"name": "mock-block-dock", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "A mock embedding application for Block Protocol blocks", | ||
@@ -38,3 +38,3 @@ "keywords": [ | ||
"dependencies": { | ||
"blockprotocol": "0.0.8", | ||
"blockprotocol": "0.0.9", | ||
"lodash": "^4.17.21", | ||
@@ -41,0 +41,0 @@ "uuid": "^8.3.2" |
@@ -5,2 +5,4 @@ # Mock Block Dock | ||
`yarn add mock-block-dock` | ||
## Usage | ||
@@ -28,2 +30,6 @@ | ||
- `updateLinks` | ||
- `getLinkedAggregations` | ||
- `createLinkedAggregations` | ||
- `deleteLinkedAggregations` | ||
- `updateLinkedAggregations` | ||
- `uploadFile` | ||
@@ -39,4 +45,7 @@ | ||
It will also pass `linkGroups` and `linkedEntities`, which will be populated once you create links between entities using `createLinks` (see [linking entities](https://blockprotocol.org/spec/block-types#linking-entities) for more). | ||
It will also pass: | ||
- `linkGroups` and `linkedEntities`, which will be populated once you create links between entities using `createLinks` (see [linking entities](https://blockprotocol.org/spec/block-types#linking-entities) for more). | ||
- `linkedAggregations`, which will be populated if you create a link from an entity to an aggregation of entities, using `createLinkedAggregations` – this includes both the definition of the aggregation operation, and the results of the operation. | ||
The block will also be re-rendered with new properties if you update them on the child directly (e.g. if you are supplying the block component wrapped by `MockBlockDock` with props from some outside state). | ||
@@ -52,3 +61,3 @@ | ||
If you prefer, you can provide your own `initialEntities` and/or `initialEntityTypes` and/or `initialLinks` as props. | ||
If you prefer, you can provide your own `initialEntities` and/or `initialEntityTypes` and/or `initialLinks` and/or `initialLinkedAggregations` as props. | ||
@@ -70,7 +79,1 @@ ```jsx | ||
``` | ||
## Note | ||
Only a subset of functionality listed in the [Block Protocol spec](https://blockprotocol.org/spec) is currently supported. | ||
We will be adding more in the coming weeks. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
163768
74
2080
75
+ Addedblockprotocol@0.0.9(transitive)
- Removedblockprotocol@0.0.8(transitive)
Updatedblockprotocol@0.0.9