immer#Draft TypeScript Examples
The following examples show how to use
immer#Draft.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MessageValueViewReducer.ts From Protoman with MIT License | 6 votes |
// Change Value Helpers
function changeValue(v: Draft<ProtobufValue>, segments: string[], value: string): void {
switch (v.type.tag) {
case 'message':
return changeMessageValue(v as Draft<MessageValue>, segments, value);
case 'primitive':
return changePrimitiveValue(v as Draft<PrimitiveValue>, segments, value);
case 'enum':
return changeEnumValue(v as Draft<EnumValue>, segments, value);
}
}
Example #2
Source File: panelReducer.ts From diagram-maker with Apache License 2.0 | 6 votes |
anchorPanel = (
draftState: Draft<DiagramMakerPanels>,
action: DragPanelAction,
) => {
const containerSize = action.payload.viewContainerSize;
const currentPanel = draftState[action.payload.id];
const { x, y } = currentPanel.position;
const rightDistance = Math.abs(containerSize.width - (x + currentPanel.size.width));
const bottomDistance = Math.abs(containerSize.height - (y + currentPanel.size.height));
if (x < ANCHOR_DISTANCE && y < ANCHOR_DISTANCE) {
currentPanel.positionAnchor = PositionAnchor.TOP_LEFT;
currentPanel.position = { x: 0, y: 0 };
} else if (rightDistance < ANCHOR_DISTANCE && y < ANCHOR_DISTANCE) {
currentPanel.positionAnchor = PositionAnchor.TOP_RIGHT;
currentPanel.position = { x: 0, y: 0 };
} else if (x < ANCHOR_DISTANCE && bottomDistance < ANCHOR_DISTANCE) {
currentPanel.positionAnchor = PositionAnchor.BOTTOM_LEFT;
currentPanel.position = { x: 0, y: 0 };
} else if (rightDistance < ANCHOR_DISTANCE && bottomDistance < ANCHOR_DISTANCE) {
currentPanel.positionAnchor = PositionAnchor.BOTTOM_RIGHT;
currentPanel.position = { x: 0, y: 0 };
}
}
Example #3
Source File: index.tsx From mutik with MIT License | 6 votes |
export function createStore<S>(initialState: S): Store<S> {
let listeners: Listener[] = [];
let currentState = initialState;
return {
get() {
return currentState;
},
set(nextState: S | UpdaterFn<S>) {
currentState =
typeof nextState === 'function'
? (nextState as UpdaterFn<S>)(currentState)
: nextState;
listeners.forEach(listener => listener());
},
on(listener: Listener) {
listeners.push(listener);
return () => this.off(listener);
},
off(listener: Listener) {
listeners = listeners.filter(fn => fn !== listener);
},
reset() {
this.set(initialState);
},
mutate(updater: (draft: Draft<S>) => void | S) {
let currState = this.get();
let nextState = immer(currState, updater);
if (nextState !== currState) this.set(nextState as S);
},
};
}
Example #4
Source File: BulkReducer.ts From Protoman with MIT License | 6 votes |
export default function BulkReducer(s: AppState, action: AnyAction): AppState {
if (BulkActionTypes.includes(action.type)) {
const a = action as BulkAction;
switch (a.type) {
case 'IMPORT_COLLECTION':
return produce(s, draft => {
const names = s.collections.map(([name]) => name);
const prefix = 'Imported';
let idx = 1;
while (names.includes(prefix + idx)) idx++;
console.log(a.collection);
draft.collections.push([prefix + idx, a.collection as Draft<Collection>]);
});
default:
return s;
}
}
return s;
}
Example #5
Source File: workspaceReducer.ts From diagram-maker with Apache License 2.0 | 6 votes |
resizeReducer = (draftState: Draft<DiagramMakerWorkspace>, action: ResizeWorkspaceAction) => {
const currentWorkspace = draftState;
currentWorkspace.viewContainerSize = action.payload.containerSize;
currentWorkspace.scale = clampZoom(
currentWorkspace.scale,
currentWorkspace.canvasSize,
currentWorkspace.viewContainerSize,
);
currentWorkspace.position = clampPosition(
currentWorkspace.position,
currentWorkspace.canvasSize,
currentWorkspace.scale,
currentWorkspace.viewContainerSize,
);
}
Example #6
Source File: MessageValueViewReducer.ts From Protoman with MIT License | 6 votes |
function changeMessageValue(msg: Draft<MessageValue>, segments: string[], value: string): void {
const fieldName = segments[0];
const [field, repeatedField, oneOfField, mapField] = findField(msg, fieldName);
if (field) {
changeValue(field, segments.slice(1), value);
} else if (repeatedField) {
const idx = parseInt(segments[1]);
changeValue(repeatedField[idx], segments.slice(2), value);
} else if (oneOfField) {
const [, selectedValue] = oneOfField;
// although segments[1](subfieldName) isn't used,
// it's included in the path just in case we later decide that we need it.
// i.e. rather than keeping just the selected value,
// we might keep all values to preserve user inputs.
changeValue(selectedValue, segments.slice(2), value);
} else if (mapField) {
const idx = parseInt(segments[1]);
const isKey = parseInt(segments[2]) === 0;
if (isKey) {
mapField[idx][0] = value;
} else {
changeValue(mapField[idx][1], segments.slice(3), value);
}
}
}
Example #7
Source File: slot.ts From textbus with GNU General Public License v3.0 | 6 votes |
/**
* 更新插槽状态的方法
* @param fn
*/
updateState(fn: (draft: Draft<T>) => void): T {
let changes!: Patch[]
let inverseChanges!: Patch[]
const oldState = this.state
const newState = produce(oldState, fn, (p, ip) => {
changes = p
inverseChanges = ip
})
this.state = newState
const applyAction: ApplyAction = {
type: 'apply',
patches: changes,
value: newState
}
this.changeMarker.markAsDirtied({
path: [],
apply: [applyAction],
unApply: [{
type: 'apply',
patches: inverseChanges,
value: oldState
}]
})
this.stateChangeEvent.next([applyAction])
return newState!
}
Example #8
Source File: data-store.ts From VIR with MIT License | 6 votes |
private removeItemReducer = (draft: Draft<DataStoreState>,
itemID: ItemID) => {
const item = draft.items.get(itemID)
if (item === undefined) {
throw new Error(`Item with ID ${itemID} does not exist`)
}
this._removeAllChildrenOf(draft, item)
if (item.parentID === undefined) {
removeValue(draft.rootItemIDs, itemID)
} else {
const parent = draft.items.get(item.parentID)
if (parent === undefined) {
throw new Error(`Parent ID ${item.parentID} does not exist`)
}
removeValue(parent.childrenIDs, itemID)
}
draft.items.delete(itemID)
this.invalidateItemID(draft, itemID)
}
Example #9
Source File: store.ts From Protoman with MIT License | 5 votes |
export function procCol(collection: Draft<Collection>): Draft<Collection> {
collection.buildError = undefined;
collection.buildStatus = 'default';
collection.flows = collection.flows.map(([fn, f]) => [fn, procFlow(f)]);
return collection;
}
Example #10
Source File: edgeReducer.ts From diagram-maker with Apache License 2.0 | 5 votes |
export default function edgeReducer<NodeType, EdgeType>(
state: DiagramMakerEdges<EdgeType> | undefined,
action: DiagramMakerAction<NodeType, EdgeType>,
): DiagramMakerEdges<EdgeType> {
if (state === undefined) {
return {};
}
switch (action.type) {
case GlobalActionsType.CREATE_ITEMS:
return produce(state, (draftState) => {
action.payload.edges.forEach((edge) => {
draftState[edge.id] = edge as Draft<DiagramMakerEdge<EdgeType>>;
});
});
case EdgeActionsType.EDGE_DELETE:
return produce(state, (draftState) => {
delete draftState[action.payload.id];
});
case (EdgeActionsType.EDGE_CREATE):
return produce(state, (draftState) => {
const {
id, src, dest, consumerData: untypedConsumerData,
} = action.payload;
const consumerData = untypedConsumerData as Draft<EdgeType>;
const diagramMakerData = {};
draftState[id] = {
consumerData,
dest,
diagramMakerData,
id,
src,
};
});
case (EdgeActionsType.EDGE_SELECT):
return produce(state, (draftState) => {
const edgeIds = Object.keys(draftState);
edgeIds.forEach((edgeId) => {
if (edgeId !== action.payload.id) {
draftState[edgeId].diagramMakerData.selected = false;
} else {
draftState[edgeId].diagramMakerData.selected = true;
}
});
});
case (WorkspaceActionsType.WORKSPACE_DESELECT):
case (NodeActionsType.NODE_SELECT):
return produce(state, (draftState) => {
const edgeIds = Object.keys(draftState);
edgeIds.forEach((edgeId) => {
draftState[edgeId].diagramMakerData.selected = false;
});
});
case (GlobalActionsType.DELETE_ITEMS):
return produce(state, (draftState) => {
const { edgeIds } = action.payload;
edgeIds.forEach((edgeId: string) => {
delete draftState[edgeId];
});
});
default:
return state;
}
}
Example #11
Source File: store.ts From Protoman with MIT License | 5 votes |
function createDefaultEnv(): Draft<Env> {
return {
vars: [],
};
}
Example #12
Source File: data-store.ts From VIR with MIT License | 5 votes |
private removeQuotaRuleReducer = (draft: Draft<DataStoreState>,
quotaRuleID: QuotaRuleID) => {
draft.quotaRules.delete(quotaRuleID)
removeValue(draft.quotaRuleOrder, quotaRuleID)
}
Example #13
Source File: workspaceReducer.ts From diagram-maker with Apache License 2.0 | 5 votes |
getNewZoomLevel = (currentState: Draft<DiagramMakerWorkspace>, action: ZoomWorkspaceAction): number => {
const zoom = currentState.scale;
const zoomFactor = Math.max(-1, Math.min(1, zoom)) * ZoomDefaults.SPEED;
const containerSize = currentState.viewContainerSize;
const newZoom = clampZoom(zoom + action.payload.zoom * zoomFactor, currentState.canvasSize, containerSize);
return newZoom;
}
Example #14
Source File: data-store.ts From VIR with MIT License | 5 votes |
private updateItemReducer = (draft: Draft<DataStoreState>,
itemDraft: ItemDraft,
options: UpdateItemOptions) => {
const itemID = itemDraft.id
const item = draft.items.get(itemID)
if (item === undefined) {
throw new Error(`Item with ID ${itemID} does not exist`)
}
const oldParentID = item.parentID
const newParentID = itemDraft.parentID
const oldStatus = item.status
const newStatus = itemDraft.status
itemDraft.applyToItem(item)
// Apply status change to children
if (oldStatus !== newStatus) {
this.setDraftSubtreeStatus(draft, item, newStatus)
}
// Change parent
if (newParentID !== oldParentID || options.anchor !== undefined) {
// Remove from old
if (oldParentID === undefined) {
removeValue(draft.rootItemIDs, itemID)
} else {
const parent = draft.items.get(oldParentID)
if (parent === undefined) {
throw new Error(`Parent ID ${oldParentID} does not exist`)
}
removeValue(parent.childrenIDs, itemID)
}
// Add to new
if (newParentID === undefined) {
insertWithOptions(draft.rootItemIDs, item.id, options)
} else {
const parent = draft.items.get(newParentID)
if (parent === undefined) {
throw new Error(`Parent ID ${newParentID} does not exist`)
}
insertWithOptions(parent.childrenIDs, item.id, options)
}
}
}
Example #15
Source File: workspaceReducer.ts From diagram-maker with Apache License 2.0 | 5 votes |
canvasResizeReducer = (draftState: Draft<DiagramMakerWorkspace>, action: ResizeWorkspaceCanvasAction) => {
const currentWorkspace = draftState;
currentWorkspace.canvasSize = action.payload.canvasSize;
}
Example #16
Source File: data-store.ts From VIR with MIT License | 5 votes |
private removeItemFromQueueReducer = (draft: Draft<DataStoreState>,
itemID: ItemID) => {
removeValue(draft.queue, itemID)
}
Example #17
Source File: index.ts From atlas with GNU General Public License v3.0 | 5 votes |
immer =
<T extends State>(config: StateCreator<T, (fn: (state: Draft<T>) => void) => void>): StateCreator<T> =>
(set, get, api) =>
config((fn) => set(produce<T>(fn)), get, api)
Example #18
Source File: mutation.ts From datart with Apache License 2.0 | 5 votes |
export function updateBy<T>(base: T, updater: (draft: Draft<T>) => void) {
return produce(base, draft => {
updater(draft);
});
}
Example #19
Source File: ProtofileManagerReducer.ts From Protoman with MIT License | 5 votes |
export default function ProtofileManagerReducer(s: AppState, action: AnyAction): AppState {
if (ProtofileManagerActionTypes.includes(action.type)) {
const a = action as ProtofileManagerActions;
switch (a.type) {
case 'SET_PROTOFILES':
return produce(s, draft => {
const collection = getByKey(draft.collections, a.collectionName);
if (collection) {
collection.protoFilepaths = a.filepaths;
collection.protoRootPath = a.rootPath;
collection.buildError = undefined;
}
});
case 'BUILD_PROTOFILES':
return produce(s, draft => {
const collection = getByKey(draft.collections, a.collectionName);
if (collection) {
collection.buildStatus = 'building';
collection.buildError = undefined;
}
});
case 'BUILD_PROTOFILES_SUCCESS':
return produce(s, draft => {
const collection = getByKey(draft.collections, a.collectionName);
if (collection) {
collection.buildStatus = 'success';
collection.buildError = undefined;
collection.protoCtx = a.ctx as Draft<ProtoCtx>;
collection.messageNames = Object.values(a.ctx.types)
.filter(t => t.tag === 'message')
.map(t => t.name);
}
});
case 'BUILD_PROTOFILES_FAILURE':
return produce(s, draft => {
const collection = getByKey(draft.collections, a.collectionName);
if (collection) {
collection.buildStatus = 'failure';
collection.buildError = a.err;
}
});
case 'RESET_PROTOFILE_STATUS':
return produce(s, draft => {
const collection = getByKey(draft.collections, a.collectionName);
if (collection) {
collection.buildStatus = 'default';
}
});
default:
return s;
}
}
return s;
}
Example #20
Source File: data-store.ts From VIR with MIT License | 5 votes |
private queueMoveReducer = (draft: Draft<DataStoreState>, itemID: ItemID,
index: number) => {
const oldIndex = draft.queue.indexOf(itemID)
if (oldIndex < 0) return
arrayMove(draft.queue, oldIndex, index)
}
Example #21
Source File: MessageValueViewReducer.ts From Protoman with MIT License | 5 votes |
function extractBody(d: Draft<AppState>): Draft<MessageValue> | undefined {
const flow = getByKey(getByKey(d.collections, d.currentCollection)?.flows, d.currentFlow);
return flow?.requestBuilder?.bodies?.protobuf;
}
Example #22
Source File: workspaceReducer.ts From diagram-maker with Apache License 2.0 | 5 votes |
dragReducer = (draftState: Draft<DiagramMakerWorkspace>, action: DragWorkspaceAction) => {
const currentWorkspace = draftState;
currentWorkspace.position = getNewDragPosition(currentWorkspace, action);
}
Example #23
Source File: data-store.ts From VIR with MIT License | 5 votes |
private quotaRuleMoveReducer = (draft: Draft<DataStoreState>,
quotaRuleID: QuotaRuleID,
index: number) => {
const oldIndex = draft.quotaRuleOrder.indexOf(quotaRuleID)
if (oldIndex < 0) return
arrayMove(draft.quotaRuleOrder, oldIndex, index)
}
Example #24
Source File: MessageValueViewReducer.ts From Protoman with MIT License | 5 votes |
function changePrimitiveValue(v: Draft<PrimitiveValue>, segment: string[], value: string): void {
console.assert(segment.length === 1 && segment[0] === '');
v.value = value;
}
Example #25
Source File: data-store.ts From VIR with MIT License | 4 votes |
/**
* NOTE: This root item must be self-repeatable.
* Returns whether the repeat is successful (or simply marked as done)
*/
private repeatSubtreeReducer = (draft: Draft<DataStoreState>,
rootItemID: ItemID,
subtree: ItemID[],
currentDate: DayID): boolean => {
const item = draft.items.get(rootItemID)
if (item === undefined) return false
const firstTask: Task = {
cost: item.cost,
end: item.dueDate,
itemID: rootItemID,
start: item.deferDate,
}
if (firstTask.end === undefined) {
item.status = ItemStatus.COMPLETED
return false
}
// Move start and end to today
let repeatOffset = 0
if (item.repeatOnCompletion) {
repeatOffset = this.getCurrentDayID() - firstTask.end
firstTask.end += repeatOffset
if (firstTask.start !== undefined) {
firstTask.start += repeatOffset
}
}
const repeat = item.repeat
if (repeat === undefined) {
item.status = ItemStatus.COMPLETED
return false
}
const repeater = DEFAULT_REPEATER_BY_TYPE.get(repeat.type)
if (repeater === undefined) {
item.status = ItemStatus.COMPLETED
return false
}
const iterator = repeater(
firstTask, this.getEffectiveInfo(item), dayIDNow() + 100000000)
let nextTask: Task | undefined = undefined
while (true) {
nextTask = iterator()
if (nextTask === undefined || nextTask.end === undefined ||
nextTask.end >= currentDate) {
break
}
}
if (nextTask === undefined) {
item.status = ItemStatus.COMPLETED
return false
}
const subtreeInfo: SubtreeRepetitionInfo[] = []
const count = subtree.length
for (let i = 0; i < count; i++) {
const subtreeItemID = subtree[i]
const subtreeItem = draft.items.get(subtreeItemID)
if (subtreeItem === undefined) continue
subtreeItem.status = ItemStatus.ACTIVE
if (subtreeItemID === rootItemID) { // Is root item
const startOffset = subtreeItem.repeatDeferOffset === undefined ?
undefined : subtreeItem.repeatDeferOffset
const endOffset = 0
subtreeInfo.push({
itemID: subtreeItemID,
startOffset,
endOffset,
})
} else {
const startOffset = subtreeItem.deferDate === undefined ? undefined :
firstTask.end - repeatOffset - subtreeItem.deferDate
const endOffset = subtreeItem.dueDate === undefined ? 0 :
firstTask.end - repeatOffset - subtreeItem.dueDate
subtreeInfo.push({
itemID: subtreeItemID,
startOffset,
endOffset,
})
}
}
const repetitionResults = generateSubtreeRepetition(
nextTask, rootItemID, subtreeInfo)
const numResults = repetitionResults.length
for (let i = 0; i < numResults; ++i) {
const result = repetitionResults[i]
const subtreeItem = draft.items.get(result.itemID)
if (subtreeItem === undefined) continue
subtreeItem.deferDate = result.deferDate
subtreeItem.dueDate = result.dueDate
}
return true
}
Example #26
Source File: nodeReducer.ts From diagram-maker with Apache License 2.0 | 4 votes |
export default function nodeReducer<NodeType, EdgeType>(
state: DiagramMakerNodes<NodeType> | undefined,
action: DiagramMakerAction<NodeType, EdgeType>,
): DiagramMakerNodes<NodeType> {
if (state === undefined) {
return {};
}
switch (action.type) {
case GlobalActionsType.CREATE_ITEMS:
return produce(state, (draftState) => {
action.payload.nodes.forEach((node) => {
draftState[node.id] = node as Draft<DiagramMakerNode<NodeType>>;
});
});
case NodeActionsType.NODE_CREATE:
return produce(state, (draftState) => {
const {
id, position, size, typeId, consumerData: untypedConsumerData,
} = action.payload;
const consumerData = untypedConsumerData as Draft<NodeType>;
draftState[id] = {
id, typeId, consumerData, diagramMakerData: { position, size },
};
});
case NodeActionsType.NODE_DELETE:
return produce(state, (draftState) => {
delete draftState[action.payload.id];
});
case EditorActionsType.FOCUS_NODE:
case NodeActionsType.NODE_SELECT:
return produce(state, (draftState) => {
const nodeIds = Object.keys(draftState);
nodeIds.forEach((nodeId) => {
if (nodeId !== action.payload.id) {
draftState[nodeId].diagramMakerData.selected = false;
} else {
draftState[nodeId].diagramMakerData.selected = true;
}
});
});
case NodeActionsType.NODE_DRAG_START:
return produce(state, (draftState) => {
const currentNode = draftState[action.payload.id];
if (currentNode) {
currentNode.diagramMakerData.dragging = true;
}
});
case NodeActionsType.NODE_DRAG:
return produce(state, (draftState) => {
const currentNode = draftState[action.payload.id];
if (currentNode) {
const { position } = action.payload;
currentNode.diagramMakerData.position = position;
// Shift all the nodes when node is dragged outside top boundary
if (position.y < 0) {
const offset = { x: 0, y: -position.y };
const nodeIds = Object.keys(draftState);
nodeIds.forEach((nodeId) => {
const oldPos = draftState[nodeId].diagramMakerData.position;
const newPos = {
x: oldPos.x + offset.x,
y: oldPos.y + offset.y,
};
draftState[nodeId].diagramMakerData.position = newPos;
});
}
// Shift all the nodes when node is dragged outside left boundary
if (position.x < 0) {
const offset = { x: -position.x, y: 0 };
const nodeIds = Object.keys(draftState);
nodeIds.forEach((nodeId) => {
const oldPos = draftState[nodeId].diagramMakerData.position;
const newPos = {
x: oldPos.x + offset.x,
y: oldPos.y + offset.y,
};
draftState[nodeId].diagramMakerData.position = newPos;
});
}
}
});
case NodeActionsType.NODE_DRAG_END:
return produce(state, (draftState) => {
const currentNode = draftState[action.payload.id];
if (currentNode) {
currentNode.diagramMakerData.dragging = false;
}
});
case EditorActionsType.UPDATE_SELECTION_MARQUEE:
return produce(state, (draftState) => {
const nodeIds = Object.keys(draftState);
nodeIds.forEach((nodeId) => {
if (isInsideBoundingBox(
draftState[nodeId].diagramMakerData.position,
draftState[nodeId].diagramMakerData.size,
action.payload.anchor,
action.payload.position,
)) {
draftState[nodeId].diagramMakerData.selected = true;
} else {
draftState[nodeId].diagramMakerData.selected = false;
}
});
});
case WorkspaceActionsType.WORKSPACE_DESELECT:
case EdgeActionsType.EDGE_SELECT:
return produce(state, (draftState) => {
const nodeIds = Object.keys(draftState);
nodeIds.forEach((nodeId) => {
draftState[nodeId].diagramMakerData.selected = false;
});
});
case WorkspaceActionsType.WORKSPACE_SELECT_ALL:
return produce(state, (draftState) => {
const nodeIds = Object.keys(draftState);
nodeIds.forEach((nodeId) => {
draftState[nodeId].diagramMakerData.selected = true;
});
});
case GlobalActionsType.DELETE_ITEMS:
return produce(state, (draftState) => {
const { nodeIds } = action.payload;
nodeIds.forEach((nodeId: string) => {
delete draftState[nodeId];
});
});
default:
return state;
}
}