Merge pull request #5181 from urbit/lf/fix-md-kick-removal

metadata-store: Handle removes on kick correctly
This commit is contained in:
Liam Fitzgerald 2021-09-06 08:28:41 +10:00 committed by GitHub
commit c5393bcf8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 66 additions and 35 deletions

View File

@ -246,15 +246,32 @@
|= [group=resource =associations:store]
=/ assocs=(list [=md-resource:store grp=resource =metadatum:store])
~(tap by associations)
:- (send-diff:mc %initial-group group associations)
=/ old-resources=(set md-resource:store) (~(get ju group-indices) group)
=/ cur-resources=(set md-resource:store) ~(key by associations)
=. state (remove-gone group (~(dif in old-resources) cur-resources))
|-
?~ assocs
state
:_ state
(send-diff:mc %initial-group group associations)
=, assocs
?> =(group grp.i)
=^ cards state
(handle-add group [md-resource metadatum]:i)
$(assocs t)
::
++ remove-gone
|= [group=resource gone=(set md-resource:store)]
^+ state
%+ roll ~(tap in gone)
|= [=md-resource:store out=_state]
%_ out
associations (~(del by associations.out) md-resource)
group-indices (~(del ju group-indices.out) group md-resource)
resource-indices (~(del by resource-indices.out) md-resource)
::
app-indices
(~(del ju app-indices.out) app-name.md-resource group resource.md-resource)
==
--
::
++ poke-import

View File

@ -1,4 +1,4 @@
import { MetadataUpdate } from '@urbit/api/metadata';
import { MetadataUpdate, Associations, ResourceAssociations } from '@urbit/api/metadata';
import _ from 'lodash';
import { Cage } from '~/types/cage';
import { BaseState } from '../state/base';
@ -12,24 +12,32 @@ export default class MetadataReducer {
}
}
function normalizeAssociations(assocs: ResourceAssociations): Associations {
return _.reduce(assocs, (acc, val) => {
const appName = val['app-name'];
const rid = val.resource;
const old = acc[appName];
return {
...acc,
[appName]: {
...old,
[rid]: val
}
};
}, {
groups: {},
graph: {}
} as Associations);
}
function removeGroup(group: string, assocs: Associations): Associations {
return _.mapValues(assocs, (val): any => _.omitBy(val, assoc => assoc.group === group));
}
const associations = (json: MetadataUpdate, state: MetadataState): MetadataState => {
const data = _.get(json, 'associations', false);
if (data) {
const metadata = state.associations;
Object.keys(data).forEach((key) => {
const val = data[key];
const appName = val['app-name'];
const rid = val.resource;
if (!(appName in metadata)) {
metadata[appName] = {};
}
if (!(rid in metadata[appName])) {
metadata[appName][rid] = {};
}
metadata[appName][rid] = val;
});
state.associations = metadata;
state.associations = normalizeAssociations(data);
}
return state;
};
@ -57,7 +65,10 @@ const add = (json: MetadataUpdate, state: MetadataState): MetadataState => {
const groupInitial = (json: MetadataUpdate, state: MetadataState): MetadataState => {
const data = _.get(json, 'initial-group', false);
if(data) {
associations(data, state);
state.associations = removeGroup(data.group, state.associations);
const { groups, graph } = normalizeAssociations(data.associations);
state.associations.graph = { ...state.associations.graph, ...graph };
state.associations.groups = { ...state.associations.groups, ...groups };
}
return state;
};

View File

@ -1,4 +1,4 @@
import { Association, Associations, MetadataUpdatePreview } from '@urbit/api';
import { Association, Associations, MetadataUpdatePreview } from '@urbit/api/metadata';
import _ from 'lodash';
import { useCallback, useEffect, useState } from 'react';
import {

View File

@ -36,7 +36,7 @@ export function GroupifyForm(props: GroupifyFormProps) {
name,
values.group?.toString() || undefined
));
let mod = association['app-name'];
let mod: string = association['app-name'];
if (association?.metadata?.config && 'graph' in association.metadata.config) {
mod = association.metadata.config.graph as AppName;
}

View File

@ -26,7 +26,7 @@ export function Resource(props: ResourceProps): ReactElement {
const notificationsCount = useHarkState(state => state.notificationsCount);
const associations = useMetadataState(state => state.associations);
const contacts = useContactState(state => state.contacts);
let app = association['app-name'];
let app: string = association['app-name'];
if (association?.metadata?.config && 'graph' in association.metadata.config) {
app = association.metadata.config.graph as AppName;
}

View File

@ -65,7 +65,7 @@ type ResourceSkeletonProps = {
export function ResourceSkeleton(props: ResourceSkeletonProps): ReactElement {
const { association, baseUrl, children } = props;
let app = association['app-name'];
let app: string = association['app-name'];
if (association?.metadata?.config && 'graph' in association.metadata.config) {
app = association.metadata.config.graph as AppName;
}

View File

@ -2,7 +2,7 @@ import _ from 'lodash';
import React, { useRef, ReactNode } from 'react';
import urbitOb from 'urbit-ob';
import { Icon, Row, Box, Text, BaseImage } from '@tlon/indigo-react';
import { Association, cite, AppName } from '@urbit/api';
import { Association, cite } from '@urbit/api';
import { HoverBoxLink } from '~/views/components/HoverBox';
import { Sigil } from '~/logic/lib/sigil';
import { useTutorialModal } from '~/views/components/useTutorialModal';
@ -176,9 +176,9 @@ export const SidebarAssociationItem = React.memo((props: {
const { association, selected } = props;
const title = getItemTitle(association) || '';
const appName = association?.['app-name'];
let mod = appName;
let mod: string = appName;
if (association?.metadata?.config && 'graph' in association.metadata.config) {
mod = association.metadata.config.graph as AppName;
mod = association.metadata.config.graph ;
}
const rid = association?.resource;
const groupPath = association?.group;

View File

@ -1,5 +1,5 @@
import { AppName, Path, Poke, uxToHex, PatpNoSig } from '../lib';
import { Association, Metadata, MetadataUpdate, MetadataUpdateAdd, MetadataUpdateRemove, MetadataEditField, MetadataUpdateEdit } from './types';
import { Path, Poke, uxToHex, PatpNoSig } from '../lib';
import { MdAppName, Association, Metadata, MetadataUpdate, MetadataUpdateAdd, MetadataUpdateRemove, MetadataEditField, MetadataUpdateEdit } from './types';
export const METADATA_UPDATE_VERSION = 2;
@ -11,7 +11,7 @@ export const metadataAction = <T extends MetadataUpdate>(data: T, version: numbe
export const add = (
ship: PatpNoSig,
appName: AppName,
appName: MdAppName,
resource: Path,
group: Path,
title: string,
@ -44,10 +44,10 @@ export const add = (
export { add as metadataAdd };
export const remove = (
appName: AppName,
appName: MdAppName,
resource: string,
group: string
): Poke<MetadataUpdateRemove> => metadataAction({
): Poke<MetadataUpdateRemove> => metadataAction<MetadataUpdateRemove>({
remove: {
group,
resource: {
@ -62,7 +62,7 @@ export { remove as metadataRemove };
export const edit = (
association: Association,
edit: MetadataEditField
): Poke<MetadataUpdateEdit> => metadataAction({
): Poke<MetadataUpdateEdit> => metadataAction<MetadataUpdateEdit>({
edit: {
group: association.group,
resource: {
@ -84,7 +84,7 @@ export const update = (
): Poke<MetadataUpdateAdd> => {
const metadata = { ...association.metadata, ...newMetadata };
metadata.color = uxToHex(metadata.color);
return metadataAction({
return metadataAction<MetadataUpdateAdd>({
add: {
group: association.group,
resource: {

View File

@ -1,4 +1,6 @@
import { AppName, Path, Patp } from '../lib';
import { Path, Patp } from '../lib';
export type MdAppName = 'groups' | 'graph';
export type MetadataUpdate =
MetadataUpdateInitial
@ -26,6 +28,7 @@ export type MetadataUpdateUpdate = {
export interface MetadataUpdateEdit {
edit: {
resource: MdResource;
group: string;
edit: MetadataEditField;
}
}
@ -41,7 +44,7 @@ export type MetadataUpdateRemove = {
export interface MdResource {
resource: string;
'app-name': AppName;
'app-name': MdAppName;
}
export interface MetadataUpdatePreview {