@casual-simulation/aux-common 3.2.6 → 3.2.7-alpha.6227012901
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Errors.d.ts +29 -0
- package/Errors.js +2 -0
- package/Errors.js.map +1 -0
- package/{aux-format-2 → bots}/AuxStateHelpers.d.ts +2 -33
- package/{aux-format-2 → bots}/AuxStateHelpers.js +1 -116
- package/bots/AuxStateHelpers.js.map +1 -0
- package/bots/Bot.d.ts +1 -1
- package/bots/BotCalculations.d.ts +4 -1
- package/bots/BotCalculations.js +62 -0
- package/bots/BotCalculations.js.map +1 -1
- package/bots/BotEvents.d.ts +859 -3401
- package/bots/BotEvents.js +133 -1529
- package/bots/BotEvents.js.map +1 -1
- package/bots/StateUpdatedEvent.d.ts +1 -1
- package/bots/StateUpdatedEvent.js +1 -1
- package/bots/StateUpdatedEvent.js.map +1 -1
- package/bots/index.d.ts +1 -0
- package/bots/index.js +1 -0
- package/bots/index.js.map +1 -1
- package/common/Action.d.ts +17 -0
- package/common/Action.js +2 -0
- package/common/Action.js.map +1 -0
- package/common/ConnectionIndicator.d.ts +29 -0
- package/common/ConnectionIndicator.js +23 -0
- package/common/ConnectionIndicator.js.map +1 -0
- package/common/ConnectionInfo.d.ts +30 -0
- package/common/ConnectionInfo.js +14 -0
- package/common/ConnectionInfo.js.map +1 -0
- package/common/ConnectionToken.d.ts +37 -0
- package/common/ConnectionToken.js +93 -0
- package/common/ConnectionToken.js.map +1 -0
- package/common/CurrentVersion.d.ts +26 -0
- package/common/CurrentVersion.js +2 -0
- package/common/CurrentVersion.js.map +1 -0
- package/common/Iterators.d.ts +19 -0
- package/common/Iterators.js +39 -0
- package/common/Iterators.js.map +1 -0
- package/common/LoadingProgress.d.ts +26 -0
- package/common/LoadingProgress.js +2 -0
- package/common/LoadingProgress.js.map +1 -0
- package/common/RemoteActions.d.ts +558 -0
- package/common/RemoteActions.js +128 -0
- package/common/RemoteActions.js.map +1 -0
- package/common/StatusUpdate.d.ts +108 -0
- package/common/StatusUpdate.js +2 -0
- package/common/StatusUpdate.js.map +1 -0
- package/common/StatusUpdateUtils.d.ts +3 -0
- package/common/StatusUpdateUtils.js +11 -0
- package/common/StatusUpdateUtils.js.map +1 -0
- package/common/index.d.ts +11 -0
- package/common/index.js +11 -0
- package/common/index.js.map +1 -0
- package/index.d.ts +4 -1
- package/index.js +4 -1
- package/index.js.map +1 -1
- package/package.json +3 -4
- package/partitions/AuxPartition.d.ts +1 -11
- package/partitions/AuxPartition.js.map +1 -1
- package/partitions/AuxPartitionConfig.d.ts +39 -123
- package/partitions/MemoryPartition.d.ts +2 -2
- package/partitions/MemoryPartition.js +2 -2
- package/partitions/MemoryPartition.js.map +1 -1
- package/partitions/OtherPlayersPartition.d.ts +6 -7
- package/partitions/OtherPlayersPartition.js +40 -54
- package/partitions/OtherPlayersPartition.js.map +1 -1
- package/partitions/PartitionUtils.d.ts +28 -1
- package/partitions/PartitionUtils.js +174 -1
- package/partitions/PartitionUtils.js.map +1 -1
- package/partitions/ProxyBridgePartition.d.ts +1 -3
- package/partitions/ProxyBridgePartition.js +0 -14
- package/partitions/ProxyBridgePartition.js.map +1 -1
- package/partitions/RemoteYjsPartition.d.ts +7 -6
- package/partitions/RemoteYjsPartition.js +55 -75
- package/partitions/RemoteYjsPartition.js.map +1 -1
- package/partitions/YjsPartition.d.ts +1 -2
- package/partitions/YjsPartition.js +3 -6
- package/partitions/YjsPartition.js.map +1 -1
- package/partitions/index.d.ts +1 -7
- package/partitions/index.js +1 -7
- package/partitions/index.js.map +1 -1
- package/test/FuzzingHelpers.d.ts +1 -1
- package/test/FuzzingHelpers.js +1 -1
- package/test/FuzzingHelpers.js.map +1 -1
- package/test/TestHelpers.d.ts +8 -0
- package/test/TestHelpers.js +23 -0
- package/test/TestHelpers.js.map +1 -1
- package/utils.d.ts +10 -5
- package/utils.js +19 -7
- package/utils.js.map +1 -1
- package/websockets/AuthenticatedConnectionClient.d.ts +26 -0
- package/websockets/AuthenticatedConnectionClient.js +61 -0
- package/websockets/AuthenticatedConnectionClient.js.map +1 -0
- package/websockets/ConnectionClient.d.ts +59 -0
- package/websockets/ConnectionClient.js +2 -0
- package/websockets/ConnectionClient.js.map +1 -0
- package/websockets/InstRecordsClient.d.ts +118 -0
- package/websockets/InstRecordsClient.js +387 -0
- package/websockets/InstRecordsClient.js.map +1 -0
- package/websockets/InstRecordsClientTimeSyncConnection.d.ts +13 -0
- package/websockets/InstRecordsClientTimeSyncConnection.js +16 -0
- package/websockets/InstRecordsClientTimeSyncConnection.js.map +1 -0
- package/websockets/MemoryConnectionClient.d.ts +19 -0
- package/websockets/MemoryConnectionClient.js +41 -0
- package/websockets/MemoryConnectionClient.js.map +1 -0
- package/websockets/WebsocketEvents.d.ts +2670 -0
- package/websockets/WebsocketEvents.js +189 -0
- package/websockets/WebsocketEvents.js.map +1 -0
- package/websockets/index.d.ts +7 -0
- package/websockets/index.js +7 -0
- package/websockets/index.js.map +1 -0
- package/yjs/YjsHelpers.d.ts +1 -1
- package/LoadingProgress.d.ts +0 -54
- package/LoadingProgress.js +0 -105
- package/LoadingProgress.js.map +0 -1
- package/aux-format-2/AuxCausalTree2.d.ts +0 -98
- package/aux-format-2/AuxCausalTree2.js +0 -616
- package/aux-format-2/AuxCausalTree2.js.map +0 -1
- package/aux-format-2/AuxOpTypes.d.ts +0 -268
- package/aux-format-2/AuxOpTypes.js +0 -240
- package/aux-format-2/AuxOpTypes.js.map +0 -1
- package/aux-format-2/AuxStateHelpers.js.map +0 -1
- package/aux-format-2/AuxWeaveHelpers.d.ts +0 -132
- package/aux-format-2/AuxWeaveHelpers.js +0 -335
- package/aux-format-2/AuxWeaveHelpers.js.map +0 -1
- package/aux-format-2/AuxWeaveReducer.d.ts +0 -37
- package/aux-format-2/AuxWeaveReducer.js +0 -980
- package/aux-format-2/AuxWeaveReducer.js.map +0 -1
- package/aux-format-2/index.d.ts +0 -7
- package/aux-format-2/index.js +0 -7
- package/aux-format-2/index.js.map +0 -1
- package/partitions/AuxPartitionRealtimeEditModeProvider.d.ts +0 -9
- package/partitions/AuxPartitionRealtimeEditModeProvider.js +0 -21
- package/partitions/AuxPartitionRealtimeEditModeProvider.js.map +0 -1
- package/partitions/BotClient.d.ts +0 -24
- package/partitions/BotClient.js +0 -2
- package/partitions/BotClient.js.map +0 -1
- package/partitions/BotPartition.d.ts +0 -45
- package/partitions/BotPartition.js +0 -186
- package/partitions/BotPartition.js.map +0 -1
- package/partitions/CausalRepoPartition.d.ts +0 -45
- package/partitions/CausalRepoPartition.js +0 -157
- package/partitions/CausalRepoPartition.js.map +0 -1
- package/partitions/MemoryBotClient.d.ts +0 -11
- package/partitions/MemoryBotClient.js +0 -41
- package/partitions/MemoryBotClient.js.map +0 -1
- package/partitions/RemoteCausalRepoHistoryPartition.d.ts +0 -53
- package/partitions/RemoteCausalRepoHistoryPartition.js +0 -206
- package/partitions/RemoteCausalRepoHistoryPartition.js.map +0 -1
- package/partitions/RemoteCausalRepoPartition.d.ts +0 -72
- package/partitions/RemoteCausalRepoPartition.js +0 -468
- package/partitions/RemoteCausalRepoPartition.js.map +0 -1
- package/runtime/AuxCompiler.d.ts +0 -258
- package/runtime/AuxCompiler.js +0 -722
- package/runtime/AuxCompiler.js.map +0 -1
- package/runtime/AuxDevice.d.ts +0 -28
- package/runtime/AuxDevice.js +0 -2
- package/runtime/AuxDevice.js.map +0 -1
- package/runtime/AuxGlobalContext.d.ts +0 -571
- package/runtime/AuxGlobalContext.js +0 -606
- package/runtime/AuxGlobalContext.js.map +0 -1
- package/runtime/AuxLibrary.d.ts +0 -2702
- package/runtime/AuxLibrary.js +0 -11046
- package/runtime/AuxLibrary.js.map +0 -1
- package/runtime/AuxLibraryDefinitions.def +0 -13139
- package/runtime/AuxRealtimeEditModeProvider.d.ts +0 -35
- package/runtime/AuxRealtimeEditModeProvider.js +0 -34
- package/runtime/AuxRealtimeEditModeProvider.js.map +0 -1
- package/runtime/AuxResults.d.ts +0 -77
- package/runtime/AuxResults.js +0 -6
- package/runtime/AuxResults.js.map +0 -1
- package/runtime/AuxRuntime.d.ts +0 -253
- package/runtime/AuxRuntime.js +0 -2700
- package/runtime/AuxRuntime.js.map +0 -1
- package/runtime/AuxRuntimeDynamicImports.d.ts +0 -14
- package/runtime/AuxRuntimeDynamicImports.js +0 -24
- package/runtime/AuxRuntimeDynamicImports.js.map +0 -1
- package/runtime/AuxVersion.d.ts +0 -39
- package/runtime/AuxVersion.js +0 -2
- package/runtime/AuxVersion.js.map +0 -1
- package/runtime/CasualOSError.d.ts +0 -37
- package/runtime/CasualOSError.js +0 -25
- package/runtime/CasualOSError.js.map +0 -1
- package/runtime/CompiledBot.d.ts +0 -106
- package/runtime/CompiledBot.js +0 -44
- package/runtime/CompiledBot.js.map +0 -1
- package/runtime/PerformanceNowPolyfill.d.ts +0 -1
- package/runtime/PerformanceNowPolyfill.js +0 -8
- package/runtime/PerformanceNowPolyfill.js.map +0 -1
- package/runtime/RuntimeBot.d.ts +0 -176
- package/runtime/RuntimeBot.js +0 -732
- package/runtime/RuntimeBot.js.map +0 -1
- package/runtime/RuntimeStateVersion.d.ts +0 -23
- package/runtime/RuntimeStateVersion.js +0 -22
- package/runtime/RuntimeStateVersion.js.map +0 -1
- package/runtime/Transpiler.d.ts +0 -174
- package/runtime/Transpiler.js +0 -611
- package/runtime/Transpiler.js.map +0 -1
- package/runtime/Utils.d.ts +0 -74
- package/runtime/Utils.js +0 -488
- package/runtime/Utils.js.map +0 -1
- package/runtime/index.d.ts +0 -9
- package/runtime/index.js +0 -9
- package/runtime/index.js.map +0 -1
- package/runtime/test/RuntimeTestHelpers.d.ts +0 -11
- package/runtime/test/RuntimeTestHelpers.js +0 -26
- package/runtime/test/RuntimeTestHelpers.js.map +0 -1
- package/runtime/test/TestScriptBotFactory.d.ts +0 -16
- package/runtime/test/TestScriptBotFactory.js +0 -107
- package/runtime/test/TestScriptBotFactory.js.map +0 -1
- /package/{runtime/BlobPolyfill.d.ts → BlobPolyfill.d.ts} +0 -0
- /package/{runtime/BlobPolyfill.js → BlobPolyfill.js} +0 -0
- /package/{runtime/BlobPolyfill.js.map → BlobPolyfill.js.map} +0 -0
|
@@ -1,980 +0,0 @@
|
|
|
1
|
-
import { iterateCausalGroup, iterateChildren, first, iterateSiblings, idEquals, } from '@casual-simulation/causal-trees/core2';
|
|
2
|
-
import { AuxOpType, validateCertSignature, validateRevocation, validateSignedValue, tagValueHash, } from './AuxOpTypes';
|
|
3
|
-
import { v5 as uuidv5 } from 'uuid';
|
|
4
|
-
import { hasValue, createBot } from '../bots/BotCalculations';
|
|
5
|
-
import { merge as lodashMerge } from 'lodash';
|
|
6
|
-
import { calculateOrderedEdits, } from './AuxWeaveHelpers';
|
|
7
|
-
import { applyTagEdit, del, edit, insert, isTagEdit, mergeEdits, preserve, } from './AuxStateHelpers';
|
|
8
|
-
export const CERT_ID_NAMESPACE = 'a1307e2b-8d80-4945-9792-2cd483c45e24';
|
|
9
|
-
export const CERTIFIED_SPACE = 'certified';
|
|
10
|
-
/**
|
|
11
|
-
* Calculates the state update needed for the given weave result from the given weave.
|
|
12
|
-
* @param weave The weave.
|
|
13
|
-
* @param result The result from the weave.
|
|
14
|
-
* @param state The object that the updates should be stored in. Use this when batching updates to reduce intermediate object allocations.
|
|
15
|
-
* @param space The space that new bots should use.
|
|
16
|
-
* @param initial Whether this is the initial update for the weave. Used to skip expensive inserts/deletes during the first load.
|
|
17
|
-
*/
|
|
18
|
-
export default function reducer(weave, result, state = {}, space, initial = false) {
|
|
19
|
-
if (result.type === 'atom_added') {
|
|
20
|
-
return atomAddedReducer(weave, result.atom, state, space, initial);
|
|
21
|
-
}
|
|
22
|
-
else if (result.type === 'atoms_added') {
|
|
23
|
-
for (let atom of result.atoms) {
|
|
24
|
-
atomAddedReducer(weave, atom, state, space, initial);
|
|
25
|
-
}
|
|
26
|
-
return state;
|
|
27
|
-
}
|
|
28
|
-
else if (result.type === 'conflict') {
|
|
29
|
-
return conflictReducer(weave, result, state, space, initial);
|
|
30
|
-
}
|
|
31
|
-
else if (result.type === 'atom_removed') {
|
|
32
|
-
return atomRemovedReducer(weave, result, state);
|
|
33
|
-
}
|
|
34
|
-
return {};
|
|
35
|
-
}
|
|
36
|
-
function atomAddedReducer(weave, atom, state, space, initial) {
|
|
37
|
-
const value = atom.value;
|
|
38
|
-
if (value.type === AuxOpType.Bot) {
|
|
39
|
-
return botAtomAddedReducer(atom, value, state, space);
|
|
40
|
-
}
|
|
41
|
-
else if (value.type === AuxOpType.Value) {
|
|
42
|
-
return valueAtomAddedReducer(weave, atom, value, state, space);
|
|
43
|
-
}
|
|
44
|
-
else if (value.type === AuxOpType.Insert && !initial) {
|
|
45
|
-
return insertAtomAddedReducer(weave, atom, value, state, space);
|
|
46
|
-
}
|
|
47
|
-
else if (value.type === AuxOpType.Delete &&
|
|
48
|
-
(!initial || !hasValue(value.start))) {
|
|
49
|
-
return deleteAtomAddedReducer(weave, atom, value, state, space);
|
|
50
|
-
}
|
|
51
|
-
else if (value.type === AuxOpType.Certificate) {
|
|
52
|
-
return certificateAtomAddedReducer(weave, atom, value, state);
|
|
53
|
-
}
|
|
54
|
-
else if (value.type === AuxOpType.Revocation) {
|
|
55
|
-
return revokeAtomAddedReducer(weave, atom, value, state);
|
|
56
|
-
}
|
|
57
|
-
else if (value.type === AuxOpType.Signature) {
|
|
58
|
-
return signatureAtomAddedReducer(weave, atom, value, state);
|
|
59
|
-
}
|
|
60
|
-
return {};
|
|
61
|
-
}
|
|
62
|
-
function atomRemovedReducer(weave, result, state) {
|
|
63
|
-
let updates = removeAtom(weave, result.ref.atom, result.ref, state);
|
|
64
|
-
for (let sibling of iterateSiblings(result.ref)) {
|
|
65
|
-
removeAtom(weave, sibling.atom, sibling, state);
|
|
66
|
-
}
|
|
67
|
-
return updates;
|
|
68
|
-
}
|
|
69
|
-
function botAtomAddedReducer(atom, value, state, space) {
|
|
70
|
-
const id = value.id;
|
|
71
|
-
return addBot(atom, id, state, space);
|
|
72
|
-
}
|
|
73
|
-
function valueAtomAddedReducer(weave, atom, value, state, space) {
|
|
74
|
-
const [val, tag, bot] = weave.referenceChain(atom.id);
|
|
75
|
-
if (!tag) {
|
|
76
|
-
return state;
|
|
77
|
-
}
|
|
78
|
-
if (tag.atom.value.type === AuxOpType.TagMask) {
|
|
79
|
-
return tagMaskValueAtomAddedReducer(weave, atom, value, tag, state, space);
|
|
80
|
-
}
|
|
81
|
-
if (!bot) {
|
|
82
|
-
return state;
|
|
83
|
-
}
|
|
84
|
-
if (bot.atom.value.type !== AuxOpType.Bot) {
|
|
85
|
-
return state;
|
|
86
|
-
}
|
|
87
|
-
if (tag.atom.value.type !== AuxOpType.Tag) {
|
|
88
|
-
return state;
|
|
89
|
-
}
|
|
90
|
-
if (!hasValue(tag.atom.value.name)) {
|
|
91
|
-
return state;
|
|
92
|
-
}
|
|
93
|
-
const tagName = tag.atom.value.name;
|
|
94
|
-
const firstValue = first(iterateCausalGroup(tag));
|
|
95
|
-
if (firstValue && firstValue.atom.hash !== atom.hash) {
|
|
96
|
-
return state;
|
|
97
|
-
}
|
|
98
|
-
const id = bot.atom.value.id;
|
|
99
|
-
const isDeleted = isBotDeleted(bot);
|
|
100
|
-
if (isDeleted) {
|
|
101
|
-
return state;
|
|
102
|
-
}
|
|
103
|
-
const sibling = first(iterateSiblings(firstValue));
|
|
104
|
-
if (sibling && sibling.atom.value.type === AuxOpType.Value) {
|
|
105
|
-
const certificates = weave.roots.filter((r) => r.atom.value.type === AuxOpType.Certificate);
|
|
106
|
-
const signature = certificates.find((cert) => {
|
|
107
|
-
for (let node of iterateChildren(cert)) {
|
|
108
|
-
if (node.atom.value.type === AuxOpType.Signature &&
|
|
109
|
-
node.atom.value.valueHash === sibling.atom.hash) {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return false;
|
|
114
|
-
});
|
|
115
|
-
if (signature) {
|
|
116
|
-
lodashMerge(state, {
|
|
117
|
-
[id]: {
|
|
118
|
-
signatures: {
|
|
119
|
-
[tagValueHash(id, tagName, sibling.atom.value.value)]: null,
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (!hasValue(value.value)) {
|
|
126
|
-
lodashMerge(state, {
|
|
127
|
-
[id]: {
|
|
128
|
-
tags: {
|
|
129
|
-
[tagName]: null,
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
return state;
|
|
134
|
-
}
|
|
135
|
-
lodashMerge(state, {
|
|
136
|
-
[id]: {
|
|
137
|
-
tags: {
|
|
138
|
-
[tagName]: value.value,
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
return state;
|
|
143
|
-
}
|
|
144
|
-
function insertAtomAddedReducer(weave, atom, op, state, space) {
|
|
145
|
-
var _a, _b;
|
|
146
|
-
const { tag: tagOrValue, bot: botOrTagMask, value, } = getTextEditNodes(weave, atom);
|
|
147
|
-
if (!tagOrValue) {
|
|
148
|
-
return state;
|
|
149
|
-
}
|
|
150
|
-
if (!botOrTagMask) {
|
|
151
|
-
return state;
|
|
152
|
-
}
|
|
153
|
-
if (botOrTagMask.atom.value.type === AuxOpType.TagMask) {
|
|
154
|
-
return insertTagMaskAtomAddedReducer(weave, atom, op, state, space, botOrTagMask, tagOrValue);
|
|
155
|
-
}
|
|
156
|
-
else if (botOrTagMask.atom.value.type !== AuxOpType.Bot) {
|
|
157
|
-
return state;
|
|
158
|
-
}
|
|
159
|
-
const id = botOrTagMask.atom.value.id;
|
|
160
|
-
if (tagOrValue.atom.value.type !== AuxOpType.Tag) {
|
|
161
|
-
return state;
|
|
162
|
-
}
|
|
163
|
-
if (!hasValue(tagOrValue.atom.value.name)) {
|
|
164
|
-
return state;
|
|
165
|
-
}
|
|
166
|
-
const tagName = tagOrValue.atom.value.name;
|
|
167
|
-
const nodes = [value, ...iterateCausalGroup(value)];
|
|
168
|
-
const edits = calculateOrderedEdits(nodes);
|
|
169
|
-
let count = 0;
|
|
170
|
-
// NOTE: the variable cannot be named "edit" because
|
|
171
|
-
// then webpack will not compile the reference to th edit() function
|
|
172
|
-
// correctly.
|
|
173
|
-
for (let e of edits) {
|
|
174
|
-
if (e.node.atom === atom) {
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
count += e.text.length;
|
|
178
|
-
}
|
|
179
|
-
let ops = [];
|
|
180
|
-
if (count > 0) {
|
|
181
|
-
ops.push(preserve(count));
|
|
182
|
-
}
|
|
183
|
-
ops.push(insert(op.text));
|
|
184
|
-
const existingValue = (_b = (_a = state === null || state === void 0 ? void 0 : state[id]) === null || _a === void 0 ? void 0 : _a.tags) === null || _b === void 0 ? void 0 : _b[tagName];
|
|
185
|
-
if (isTagEdit(existingValue)) {
|
|
186
|
-
lodashMerge(state, {
|
|
187
|
-
[id]: {
|
|
188
|
-
tags: {
|
|
189
|
-
[tagName]: mergeEdits(existingValue, edit({ [atom.id.site]: atom.id.timestamp }, ...ops)),
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
let tagEdit = edit({ [atom.id.site]: atom.id.timestamp }, ...ops);
|
|
196
|
-
let finalValue;
|
|
197
|
-
if (hasValue(existingValue)) {
|
|
198
|
-
finalValue = applyTagEdit(existingValue, tagEdit);
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
finalValue = tagEdit;
|
|
202
|
-
}
|
|
203
|
-
lodashMerge(state, {
|
|
204
|
-
[id]: {
|
|
205
|
-
tags: {
|
|
206
|
-
[tagName]: finalValue,
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
return state;
|
|
212
|
-
}
|
|
213
|
-
function insertTagMaskAtomAddedReducer(weave, atom, op, state, space, tagMask, value) {
|
|
214
|
-
var _a, _b, _c;
|
|
215
|
-
if (!hasValue(tagMask.atom.value.botId)) {
|
|
216
|
-
return state;
|
|
217
|
-
}
|
|
218
|
-
if (!hasValue(tagMask.atom.value.name)) {
|
|
219
|
-
return state;
|
|
220
|
-
}
|
|
221
|
-
const id = tagMask.atom.value.botId;
|
|
222
|
-
const tagName = tagMask.atom.value.name;
|
|
223
|
-
if (value.atom.value.type !== AuxOpType.Value) {
|
|
224
|
-
return state;
|
|
225
|
-
}
|
|
226
|
-
const nodes = [value, ...iterateCausalGroup(value)];
|
|
227
|
-
const edits = calculateOrderedEdits(nodes);
|
|
228
|
-
let count = 0;
|
|
229
|
-
// NOTE: the variable cannot be named "edit" because
|
|
230
|
-
// then webpack will not compile the reference to th edit() function
|
|
231
|
-
// correctly.
|
|
232
|
-
for (let e of edits) {
|
|
233
|
-
if (e.node.atom === atom) {
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
count += e.text.length;
|
|
237
|
-
}
|
|
238
|
-
let ops = [];
|
|
239
|
-
if (count > 0) {
|
|
240
|
-
ops.push(preserve(count));
|
|
241
|
-
}
|
|
242
|
-
ops.push(insert(op.text));
|
|
243
|
-
const existingValue = (_c = (_b = (_a = state === null || state === void 0 ? void 0 : state[id]) === null || _a === void 0 ? void 0 : _a.masks) === null || _b === void 0 ? void 0 : _b[space]) === null || _c === void 0 ? void 0 : _c[tagName];
|
|
244
|
-
if (isTagEdit(existingValue)) {
|
|
245
|
-
lodashMerge(state, {
|
|
246
|
-
[id]: {
|
|
247
|
-
masks: {
|
|
248
|
-
[space]: {
|
|
249
|
-
[tagName]: mergeEdits(existingValue, edit({ [atom.id.site]: atom.id.timestamp }, ...ops)),
|
|
250
|
-
},
|
|
251
|
-
},
|
|
252
|
-
},
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
let tagEdit = edit({ [atom.id.site]: atom.id.timestamp }, ...ops);
|
|
257
|
-
let finalValue;
|
|
258
|
-
if (hasValue(existingValue)) {
|
|
259
|
-
finalValue = applyTagEdit(existingValue, tagEdit);
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
finalValue = tagEdit;
|
|
263
|
-
}
|
|
264
|
-
lodashMerge(state, {
|
|
265
|
-
[id]: {
|
|
266
|
-
masks: {
|
|
267
|
-
[space]: {
|
|
268
|
-
[tagName]: finalValue,
|
|
269
|
-
},
|
|
270
|
-
},
|
|
271
|
-
},
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
return state;
|
|
275
|
-
}
|
|
276
|
-
function deleteTextReducer(weave, atom, value, state, space) {
|
|
277
|
-
var _a, _b;
|
|
278
|
-
const { tag: tagOrValue, bot: botOrTagMask, values, value: valueNode, } = getTextEditNodes(weave, atom);
|
|
279
|
-
if (!tagOrValue) {
|
|
280
|
-
return state;
|
|
281
|
-
}
|
|
282
|
-
if (!botOrTagMask) {
|
|
283
|
-
return state;
|
|
284
|
-
}
|
|
285
|
-
if (botOrTagMask.atom.value.type === AuxOpType.TagMask) {
|
|
286
|
-
return deleteTagMaskTextReducer(weave, atom, value, state, space, botOrTagMask, tagOrValue, values);
|
|
287
|
-
}
|
|
288
|
-
else if (botOrTagMask.atom.value.type !== AuxOpType.Bot) {
|
|
289
|
-
return state;
|
|
290
|
-
}
|
|
291
|
-
if (botOrTagMask.atom.value.type !== AuxOpType.Bot) {
|
|
292
|
-
return state;
|
|
293
|
-
}
|
|
294
|
-
if (tagOrValue.atom.value.type !== AuxOpType.Tag) {
|
|
295
|
-
return state;
|
|
296
|
-
}
|
|
297
|
-
if (!hasValue(tagOrValue.atom.value.name)) {
|
|
298
|
-
return state;
|
|
299
|
-
}
|
|
300
|
-
const tagName = tagOrValue.atom.value.name;
|
|
301
|
-
const id = botOrTagMask.atom.value.id;
|
|
302
|
-
const nodes = [valueNode, ...iterateCausalGroup(valueNode)];
|
|
303
|
-
const filtered = nodes.filter((n) => !idEquals(n.atom.id, atom.id));
|
|
304
|
-
const edits = calculateOrderedEdits(filtered, true);
|
|
305
|
-
let ops = [];
|
|
306
|
-
for (let { count, length } of findDeletePoints(edits, atom, value)) {
|
|
307
|
-
if (count > 0) {
|
|
308
|
-
ops.push(preserve(count));
|
|
309
|
-
}
|
|
310
|
-
ops.push(del(length));
|
|
311
|
-
}
|
|
312
|
-
if (ops.length > 0) {
|
|
313
|
-
const existingValue = (_b = (_a = state === null || state === void 0 ? void 0 : state[id]) === null || _a === void 0 ? void 0 : _a.tags) === null || _b === void 0 ? void 0 : _b[tagName];
|
|
314
|
-
if (isTagEdit(existingValue)) {
|
|
315
|
-
lodashMerge(state, {
|
|
316
|
-
[id]: {
|
|
317
|
-
tags: {
|
|
318
|
-
[tagName]: mergeEdits(existingValue, edit({ [atom.id.site]: atom.id.timestamp }, ...ops)),
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
const tagEdit = edit({ [atom.id.site]: atom.id.timestamp }, ...ops);
|
|
325
|
-
let finalValue;
|
|
326
|
-
if (hasValue(existingValue)) {
|
|
327
|
-
finalValue = applyTagEdit(existingValue, tagEdit);
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
finalValue = tagEdit;
|
|
331
|
-
}
|
|
332
|
-
lodashMerge(state, {
|
|
333
|
-
[id]: {
|
|
334
|
-
tags: {
|
|
335
|
-
[tagName]: finalValue,
|
|
336
|
-
},
|
|
337
|
-
},
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
return state;
|
|
342
|
-
}
|
|
343
|
-
function deleteTagMaskTextReducer(weave, atom, op, state, space, tagMask, value, values) {
|
|
344
|
-
var _a, _b, _c;
|
|
345
|
-
if (value.atom.value.type !== AuxOpType.Value) {
|
|
346
|
-
return state;
|
|
347
|
-
}
|
|
348
|
-
if (!hasValue(tagMask.atom.value.botId)) {
|
|
349
|
-
return state;
|
|
350
|
-
}
|
|
351
|
-
if (!hasValue(tagMask.atom.value.name)) {
|
|
352
|
-
return state;
|
|
353
|
-
}
|
|
354
|
-
const tagName = tagMask.atom.value.name;
|
|
355
|
-
const id = tagMask.atom.value.botId;
|
|
356
|
-
const nodes = [value, ...iterateCausalGroup(value)];
|
|
357
|
-
const filtered = nodes.filter((n) => !idEquals(n.atom.id, atom.id));
|
|
358
|
-
const edits = calculateOrderedEdits(filtered, true);
|
|
359
|
-
let ops = [];
|
|
360
|
-
for (let { count, length } of findDeletePoints(edits, atom, op)) {
|
|
361
|
-
if (count > 0) {
|
|
362
|
-
ops.push(preserve(count));
|
|
363
|
-
}
|
|
364
|
-
ops.push(del(length));
|
|
365
|
-
}
|
|
366
|
-
if (ops.length > 0) {
|
|
367
|
-
const existingValue = (_c = (_b = (_a = state === null || state === void 0 ? void 0 : state[id]) === null || _a === void 0 ? void 0 : _a.masks) === null || _b === void 0 ? void 0 : _b[space]) === null || _c === void 0 ? void 0 : _c[tagName];
|
|
368
|
-
if (isTagEdit(existingValue)) {
|
|
369
|
-
lodashMerge(state, {
|
|
370
|
-
[id]: {
|
|
371
|
-
masks: {
|
|
372
|
-
[space]: {
|
|
373
|
-
[tagName]: mergeEdits(existingValue, edit({ [atom.id.site]: atom.id.timestamp }, ...ops)),
|
|
374
|
-
},
|
|
375
|
-
},
|
|
376
|
-
},
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
const tagEdit = edit({ [atom.id.site]: atom.id.timestamp }, ...ops);
|
|
381
|
-
let finalValue;
|
|
382
|
-
if (hasValue(existingValue)) {
|
|
383
|
-
finalValue = applyTagEdit(existingValue, tagEdit);
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
finalValue = tagEdit;
|
|
387
|
-
}
|
|
388
|
-
lodashMerge(state, {
|
|
389
|
-
[id]: {
|
|
390
|
-
masks: {
|
|
391
|
-
[space]: {
|
|
392
|
-
[tagName]: finalValue,
|
|
393
|
-
},
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
return state;
|
|
400
|
-
}
|
|
401
|
-
/**
|
|
402
|
-
* Finds all of the points that should be deleted for the given delete op and text segments.
|
|
403
|
-
* @param edits The edits.
|
|
404
|
-
* @param atom The delete atom.
|
|
405
|
-
* @param value The delete op.
|
|
406
|
-
*/
|
|
407
|
-
export function* findDeletePoints(edits, atom, value) {
|
|
408
|
-
// The total number of characters that we have processed.
|
|
409
|
-
// Used to determine where the final delete point should be.
|
|
410
|
-
let count = 0;
|
|
411
|
-
// The number of charactesr that we have processed
|
|
412
|
-
// for the delete atom's cause.
|
|
413
|
-
// Used to determine if the delete applies to an edit.
|
|
414
|
-
let nodeCount = 0;
|
|
415
|
-
// The number of characters that should be deleted.
|
|
416
|
-
let length = 0;
|
|
417
|
-
// Whether we have created a delete point during the calculation.
|
|
418
|
-
let createdDelete = false;
|
|
419
|
-
// NOTE: the variable cannot be named "edit" because
|
|
420
|
-
// then webpack will not compile the reference to th edit() function
|
|
421
|
-
// correctly.
|
|
422
|
-
for (let e of edits) {
|
|
423
|
-
let removedText = false;
|
|
424
|
-
// We only care about edits that this delete is acting on.
|
|
425
|
-
if (idEquals(e.node.atom.id, atom.cause)) {
|
|
426
|
-
// We also only care about edits that this atom affects.
|
|
427
|
-
// Basically we want to filter out all edits that the delete doesn't contain.
|
|
428
|
-
if (nodeCount + e.marked.length > value.start) {
|
|
429
|
-
// Go through each character in the edit and determine
|
|
430
|
-
// if it should be deleted or if it has already been deleted.
|
|
431
|
-
for (let i = 0; i < e.marked.length && i < value.end - e.offset; i++) {
|
|
432
|
-
const char = e.marked[i];
|
|
433
|
-
if (i >= value.start - e.offset) {
|
|
434
|
-
if (char !== '\0') {
|
|
435
|
-
// the character has not been deleted
|
|
436
|
-
// and is in the delete atom range so
|
|
437
|
-
// we make sure to delete it.
|
|
438
|
-
length += 1;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
else {
|
|
442
|
-
if (char === '\0') {
|
|
443
|
-
// Character is before where the edit takes place
|
|
444
|
-
// and has already been deleted so we adjust
|
|
445
|
-
// the edit point.
|
|
446
|
-
count -= 1;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
if (length > 0) {
|
|
451
|
-
if (!createdDelete) {
|
|
452
|
-
// Take into account the starting point of the delete
|
|
453
|
-
// and the offset.
|
|
454
|
-
// Future delete points do not need this
|
|
455
|
-
// because all delete atoms represent a contigious
|
|
456
|
-
// range relative to the cause atom.
|
|
457
|
-
// As a result, all subsequent delete points
|
|
458
|
-
// will start at the same point that the edit starts.
|
|
459
|
-
count += value.start - e.offset;
|
|
460
|
-
}
|
|
461
|
-
createdDelete = true;
|
|
462
|
-
removedText = true;
|
|
463
|
-
yield {
|
|
464
|
-
count,
|
|
465
|
-
length,
|
|
466
|
-
};
|
|
467
|
-
length = 0;
|
|
468
|
-
count = 0;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
nodeCount += e.marked.length;
|
|
472
|
-
}
|
|
473
|
-
// If we created a delete point in this round then
|
|
474
|
-
// we should not count the node text that the delete
|
|
475
|
-
// was created for.
|
|
476
|
-
if (!removedText) {
|
|
477
|
-
count += e.text.length;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
/**
|
|
482
|
-
* Determines the number of characters that sibling nodes offset the final text insertion/deletion point.
|
|
483
|
-
* @param weave The weave.
|
|
484
|
-
* @param node The node that is represents the insertion/deletion operation.
|
|
485
|
-
* @param offset The character offset that the insertion/deletion takes place at.
|
|
486
|
-
* @param length The length of the insertion/deletion.
|
|
487
|
-
*/
|
|
488
|
-
function calculateSiblingOffset(weave, node, offset, length) {
|
|
489
|
-
const parent = weave.getNode(node.atom.cause);
|
|
490
|
-
const children = [...iterateChildren(parent)];
|
|
491
|
-
let count = 0;
|
|
492
|
-
let overlap = 0;
|
|
493
|
-
// iterating atoms causes us to move from the newest (highest timestamps/priority) to the
|
|
494
|
-
// oldest (lowest timestamps/priority).
|
|
495
|
-
// We use this variable to procedurally keep track of whether the current atom is newer or older.
|
|
496
|
-
// This allows the weave to use whatever logic for sorting atoms that it wants and we can adapt.
|
|
497
|
-
let newer = true;
|
|
498
|
-
for (let n of children) {
|
|
499
|
-
if (n === node) {
|
|
500
|
-
newer = false;
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
if (n.atom.value.type === AuxOpType.Insert) {
|
|
504
|
-
if (!newer && n.atom.value.index <= offset) {
|
|
505
|
-
count += n.atom.value.text.length;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
else if (n.atom.value.type === AuxOpType.Delete) {
|
|
509
|
-
if (n.atom.value.start <= offset) {
|
|
510
|
-
const deleteStart = n.atom.value.start;
|
|
511
|
-
const deleteEnd = n.atom.value.end;
|
|
512
|
-
const deleteCount = deleteEnd - deleteStart;
|
|
513
|
-
const shrink = -deleteCount;
|
|
514
|
-
const nodeStart = offset;
|
|
515
|
-
const nodeEnd = offset + length;
|
|
516
|
-
let startOffset = 0;
|
|
517
|
-
// If the current atom is an insert atom and
|
|
518
|
-
// it starts at the same spot that the delete does,
|
|
519
|
-
// then we need to make sure that startOffset is set to 1.
|
|
520
|
-
// This is because while deletes can overlap, inserts cannot overlap deletes.
|
|
521
|
-
// As a result, any insert that shares a starting point with a delete
|
|
522
|
-
// needs to be ordered as occuring before or after the delete.
|
|
523
|
-
// Inserts that are treated as occuring before the delete will not be affected
|
|
524
|
-
// by the delete while inserts that are treated as happening after the delete will be affected.
|
|
525
|
-
if (node.atom.value.type === AuxOpType.Insert &&
|
|
526
|
-
nodeStart <= deleteEnd) {
|
|
527
|
-
startOffset = offset - n.atom.value.start;
|
|
528
|
-
if (startOffset === 0) {
|
|
529
|
-
startOffset = deleteCount;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
// abcdefg
|
|
533
|
-
// |--|
|
|
534
|
-
// 123
|
|
535
|
-
const endOffset = 0; //Math.abs(length - deleteCount);
|
|
536
|
-
const startOverlap = Math.max(0, deleteStart - nodeStart);
|
|
537
|
-
const endOverlap = Math.max(0, nodeEnd - deleteEnd);
|
|
538
|
-
const totalOverlap = Math.max(0, length - (startOverlap + endOverlap));
|
|
539
|
-
overlap += totalOverlap;
|
|
540
|
-
count += startOffset + shrink;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
return { offset: count, overlap };
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* Gets the weave nodes needed for a text edit.
|
|
548
|
-
* Returns the bot node, tag node, and value/insert nodes.
|
|
549
|
-
*/
|
|
550
|
-
export function getTextEditNodes(weave, atom) {
|
|
551
|
-
const nodes = weave.referenceChain(atom.id);
|
|
552
|
-
const bot = nodes[nodes.length - 1];
|
|
553
|
-
const value = nodes[nodes.length - 3];
|
|
554
|
-
const tag = nodes[nodes.length - 2];
|
|
555
|
-
const values = bot.atom.value.type === AuxOpType.Bot
|
|
556
|
-
? nodes.slice(0, nodes.length - 2)
|
|
557
|
-
: nodes.slice(0, nodes.length - 1);
|
|
558
|
-
return {
|
|
559
|
-
tag,
|
|
560
|
-
bot,
|
|
561
|
-
value,
|
|
562
|
-
values,
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
function tagMaskValueAtomAddedReducer(weave, atom, value, tag, state, space) {
|
|
566
|
-
if (!hasValue(space)) {
|
|
567
|
-
return state;
|
|
568
|
-
}
|
|
569
|
-
if (!hasValue(tag.atom.value.name)) {
|
|
570
|
-
return state;
|
|
571
|
-
}
|
|
572
|
-
const tagName = tag.atom.value.name;
|
|
573
|
-
const id = tag.atom.value.botId;
|
|
574
|
-
const firstValue = first(iterateCausalGroup(tag));
|
|
575
|
-
if (firstValue && firstValue.atom.hash !== atom.hash) {
|
|
576
|
-
return state;
|
|
577
|
-
}
|
|
578
|
-
if (!hasValue(value.value)) {
|
|
579
|
-
lodashMerge(state, {
|
|
580
|
-
[id]: {
|
|
581
|
-
masks: {
|
|
582
|
-
[space]: {
|
|
583
|
-
[tagName]: null,
|
|
584
|
-
},
|
|
585
|
-
},
|
|
586
|
-
},
|
|
587
|
-
});
|
|
588
|
-
return state;
|
|
589
|
-
}
|
|
590
|
-
lodashMerge(state, {
|
|
591
|
-
[id]: {
|
|
592
|
-
masks: {
|
|
593
|
-
[space]: {
|
|
594
|
-
[tagName]: value.value,
|
|
595
|
-
},
|
|
596
|
-
},
|
|
597
|
-
},
|
|
598
|
-
});
|
|
599
|
-
return state;
|
|
600
|
-
}
|
|
601
|
-
function deleteAtomAddedReducer(weave, atom, value, state, space) {
|
|
602
|
-
const parent = weave.getNode(atom.cause);
|
|
603
|
-
if (!parent) {
|
|
604
|
-
return state;
|
|
605
|
-
}
|
|
606
|
-
if (parent.atom.value.type === AuxOpType.Bot) {
|
|
607
|
-
return deleteBotReducer(weave, parent, atom, state);
|
|
608
|
-
}
|
|
609
|
-
else if (parent.atom.value.type === AuxOpType.Insert ||
|
|
610
|
-
parent.atom.value.type === AuxOpType.Value) {
|
|
611
|
-
return deleteTextReducer(weave, atom, value, state, space);
|
|
612
|
-
}
|
|
613
|
-
return state;
|
|
614
|
-
}
|
|
615
|
-
function certificateAtomAddedReducer(weave, atom, value, state) {
|
|
616
|
-
const botId = certificateId(atom);
|
|
617
|
-
let signerId;
|
|
618
|
-
if (atom.cause) {
|
|
619
|
-
if (!isCertificateChainValid(weave, atom)) {
|
|
620
|
-
return state;
|
|
621
|
-
}
|
|
622
|
-
signerId = certificateId(weave.getNode(atom.cause).atom);
|
|
623
|
-
}
|
|
624
|
-
else {
|
|
625
|
-
if (!validateCertSignature(null, atom)) {
|
|
626
|
-
return state;
|
|
627
|
-
}
|
|
628
|
-
signerId = botId;
|
|
629
|
-
}
|
|
630
|
-
lodashMerge(state, {
|
|
631
|
-
[botId]: createBot(botId, {
|
|
632
|
-
keypair: value.keypair,
|
|
633
|
-
signature: value.signature,
|
|
634
|
-
signingCertificate: signerId,
|
|
635
|
-
atom: atom,
|
|
636
|
-
}, CERTIFIED_SPACE),
|
|
637
|
-
});
|
|
638
|
-
return state;
|
|
639
|
-
}
|
|
640
|
-
function isCertificateChainValid(weave, atom) {
|
|
641
|
-
const chain = weave.referenceChain(atom.cause);
|
|
642
|
-
let i = 0;
|
|
643
|
-
let signee = atom;
|
|
644
|
-
while (i < chain.length) {
|
|
645
|
-
let signer = chain[i];
|
|
646
|
-
// Ensure that the tree is structured properly
|
|
647
|
-
if (signer.atom.value.type !== AuxOpType.Certificate) {
|
|
648
|
-
return false;
|
|
649
|
-
}
|
|
650
|
-
// Check that the certificate's signature is valid
|
|
651
|
-
const signerCert = signer.atom;
|
|
652
|
-
if (!validateCertSignature(signerCert, signee)) {
|
|
653
|
-
return false;
|
|
654
|
-
}
|
|
655
|
-
if (isCertDirectlyRevoked(weave, signer)) {
|
|
656
|
-
return false;
|
|
657
|
-
}
|
|
658
|
-
signee = signerCert;
|
|
659
|
-
i++;
|
|
660
|
-
}
|
|
661
|
-
// Assert that the last certificate is self signed
|
|
662
|
-
if (!!signee.cause) {
|
|
663
|
-
return false;
|
|
664
|
-
}
|
|
665
|
-
if (!validateCertSignature(null, signee)) {
|
|
666
|
-
return false;
|
|
667
|
-
}
|
|
668
|
-
let signeeRef = weave.getNode(signee.id);
|
|
669
|
-
if (isCertDirectlyRevoked(weave, signeeRef)) {
|
|
670
|
-
return false;
|
|
671
|
-
}
|
|
672
|
-
return true;
|
|
673
|
-
}
|
|
674
|
-
function revokeAtomAddedReducer(weave, atom, value, state) {
|
|
675
|
-
const parent = weave.getNode(atom.cause);
|
|
676
|
-
if (!parent) {
|
|
677
|
-
return state;
|
|
678
|
-
}
|
|
679
|
-
if (parent.atom.value.type === AuxOpType.Certificate) {
|
|
680
|
-
if (!isRevocationValid(weave, atom, parent)) {
|
|
681
|
-
return state;
|
|
682
|
-
}
|
|
683
|
-
return certificateRemovedAtomReducer(weave, parent.atom, parent.atom.value, parent, state);
|
|
684
|
-
}
|
|
685
|
-
else if (parent.atom.value.type === AuxOpType.Signature) {
|
|
686
|
-
// The signing certificate must be the same as the one that created the signature
|
|
687
|
-
if (!isRevocationValid(weave, atom, parent)) {
|
|
688
|
-
return state;
|
|
689
|
-
}
|
|
690
|
-
return signatureRemovedAtomReducer(weave, parent.atom, parent.atom.value, state);
|
|
691
|
-
}
|
|
692
|
-
return state;
|
|
693
|
-
}
|
|
694
|
-
function signatureAtomAddedReducer(weave, atom, value, state) {
|
|
695
|
-
const parent = weave.getNode(atom.cause);
|
|
696
|
-
if (!parent) {
|
|
697
|
-
return state;
|
|
698
|
-
}
|
|
699
|
-
if (parent.atom.value.type !== AuxOpType.Certificate) {
|
|
700
|
-
return state;
|
|
701
|
-
}
|
|
702
|
-
const cert = parent.atom;
|
|
703
|
-
const signature = atom;
|
|
704
|
-
const [val, tag, bot] = weave.referenceChain(value.valueId);
|
|
705
|
-
if (!val || !tag || !bot) {
|
|
706
|
-
return state;
|
|
707
|
-
}
|
|
708
|
-
if (val.atom.hash !== value.valueHash) {
|
|
709
|
-
return state;
|
|
710
|
-
}
|
|
711
|
-
if (bot.atom.value.type !== AuxOpType.Bot) {
|
|
712
|
-
return state;
|
|
713
|
-
}
|
|
714
|
-
if (tag.atom.value.type !== AuxOpType.Tag) {
|
|
715
|
-
return state;
|
|
716
|
-
}
|
|
717
|
-
if (!hasValue(tag.atom.value.name)) {
|
|
718
|
-
return state;
|
|
719
|
-
}
|
|
720
|
-
const tagName = tag.atom.value.name;
|
|
721
|
-
const id = bot.atom.value.id;
|
|
722
|
-
const isDeleted = isBotDeleted(bot);
|
|
723
|
-
if (isDeleted) {
|
|
724
|
-
return state;
|
|
725
|
-
}
|
|
726
|
-
if (!isCertificateChainValid(weave, cert)) {
|
|
727
|
-
return state;
|
|
728
|
-
}
|
|
729
|
-
const realValue = val.atom;
|
|
730
|
-
if (!validateSignedValue(cert, signature, realValue)) {
|
|
731
|
-
return state;
|
|
732
|
-
}
|
|
733
|
-
const hash = tagValueHash(id, tagName, realValue.value.value);
|
|
734
|
-
lodashMerge(state, {
|
|
735
|
-
[id]: {
|
|
736
|
-
signatures: {
|
|
737
|
-
[hash]: tagName,
|
|
738
|
-
},
|
|
739
|
-
},
|
|
740
|
-
});
|
|
741
|
-
return state;
|
|
742
|
-
}
|
|
743
|
-
/**
|
|
744
|
-
* Determines if the given certificate has been revoked directly.
|
|
745
|
-
* @param weave The weave.
|
|
746
|
-
* @param cert The certificate to check.
|
|
747
|
-
*/
|
|
748
|
-
function isCertDirectlyRevoked(weave, cert) {
|
|
749
|
-
// Check if the certificate has been revoked.
|
|
750
|
-
for (let child of iterateChildren(cert)) {
|
|
751
|
-
if (child.atom.value.type === AuxOpType.Revocation &&
|
|
752
|
-
isRevocationValid(weave, child.atom, cert)) {
|
|
753
|
-
return true;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
return false;
|
|
757
|
-
}
|
|
758
|
-
function isRevocationValid(weave, revocation, parent) {
|
|
759
|
-
// The signing certificate must be the parent or a grandparent
|
|
760
|
-
const chain = weave.referenceChain(parent.atom.id);
|
|
761
|
-
let signingCert;
|
|
762
|
-
for (let node of chain) {
|
|
763
|
-
if (node.atom.value.type === AuxOpType.Certificate &&
|
|
764
|
-
node.atom.hash === revocation.value.certHash) {
|
|
765
|
-
signingCert = node;
|
|
766
|
-
break;
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
if (!signingCert) {
|
|
770
|
-
// No signing cert - return without changes
|
|
771
|
-
return false;
|
|
772
|
-
}
|
|
773
|
-
if (!validateRevocation(signingCert.atom, revocation, parent.atom)) {
|
|
774
|
-
return false;
|
|
775
|
-
}
|
|
776
|
-
return true;
|
|
777
|
-
}
|
|
778
|
-
function deleteBotReducer(weave, bot, atom, state) {
|
|
779
|
-
const firstValue = first(iterateCausalGroup(bot));
|
|
780
|
-
if (firstValue && firstValue.atom.hash !== atom.hash) {
|
|
781
|
-
return state;
|
|
782
|
-
}
|
|
783
|
-
const id = bot.atom.value.id;
|
|
784
|
-
return deleteBot(weave, id, state);
|
|
785
|
-
}
|
|
786
|
-
function conflictReducer(weave, result, state, space, initial) {
|
|
787
|
-
if (!result.loserRef) {
|
|
788
|
-
return state;
|
|
789
|
-
}
|
|
790
|
-
let update = state;
|
|
791
|
-
if (result.loser.value.type === AuxOpType.Bot) {
|
|
792
|
-
// Iterate all the tags of the loser
|
|
793
|
-
// and delete them.
|
|
794
|
-
for (let node of iterateChildren(result.loserRef)) {
|
|
795
|
-
if (node.atom.value.type === AuxOpType.Tag) {
|
|
796
|
-
deleteTag(node.atom, result.loser, update);
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
else if (result.loser.value.type === AuxOpType.Tag) {
|
|
801
|
-
const bot = weave.getNode(result.loser.cause).atom;
|
|
802
|
-
if (bot.value.type === AuxOpType.Bot) {
|
|
803
|
-
deleteTag(result.loser, bot, update);
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
else if (result.loser.value.type === AuxOpType.Certificate) {
|
|
807
|
-
certificateRemovedAtomReducer(weave, result.loser, result.loser.value, result.loserRef, update);
|
|
808
|
-
}
|
|
809
|
-
else if (result.loser.value.type === AuxOpType.Revocation) {
|
|
810
|
-
revocationRemovedAtomReducer(weave, result.loser, result.loser.value, update);
|
|
811
|
-
}
|
|
812
|
-
else if (result.loser.value.type === AuxOpType.Signature) {
|
|
813
|
-
signatureRemovedAtomReducer(weave, result.loser, result.loser.value, update);
|
|
814
|
-
}
|
|
815
|
-
atomAddedReducer(weave, result.winner, update, space, initial);
|
|
816
|
-
return update;
|
|
817
|
-
}
|
|
818
|
-
function addBot(atom, botId, state, space) {
|
|
819
|
-
if (atom.cause !== null) {
|
|
820
|
-
return state;
|
|
821
|
-
}
|
|
822
|
-
lodashMerge(state, {
|
|
823
|
-
[botId]: createBot(botId, undefined, space),
|
|
824
|
-
});
|
|
825
|
-
return state;
|
|
826
|
-
}
|
|
827
|
-
function deleteBot(weave, id, state) {
|
|
828
|
-
lodashMerge(state, {
|
|
829
|
-
[id]: null,
|
|
830
|
-
});
|
|
831
|
-
return state;
|
|
832
|
-
}
|
|
833
|
-
function deleteTag(tag, bot, state) {
|
|
834
|
-
const value = tag.value;
|
|
835
|
-
const id = bot.value.id;
|
|
836
|
-
lodashMerge(state, {
|
|
837
|
-
[id]: {
|
|
838
|
-
tags: {
|
|
839
|
-
[value.name]: null,
|
|
840
|
-
},
|
|
841
|
-
},
|
|
842
|
-
});
|
|
843
|
-
return state;
|
|
844
|
-
}
|
|
845
|
-
function isBotDeleted(bot) {
|
|
846
|
-
const firstValue = first(iterateCausalGroup(bot));
|
|
847
|
-
return firstValue.atom.value.type === AuxOpType.Delete;
|
|
848
|
-
}
|
|
849
|
-
function removeAtom(weave, atom, node, state) {
|
|
850
|
-
if (atom.value.type === AuxOpType.Bot) {
|
|
851
|
-
return deleteBot(weave, atom.value.id, state);
|
|
852
|
-
}
|
|
853
|
-
else if (atom.value.type === AuxOpType.Value) {
|
|
854
|
-
return valueRemovedAtomReducer(weave, atom, atom.value, state);
|
|
855
|
-
}
|
|
856
|
-
else if (atom.value.type === AuxOpType.Certificate) {
|
|
857
|
-
return certificateRemovedAtomReducer(weave, atom, atom.value, node, state);
|
|
858
|
-
}
|
|
859
|
-
else if (atom.value.type === AuxOpType.Revocation) {
|
|
860
|
-
return revocationRemovedAtomReducer(weave, atom, atom.value, state);
|
|
861
|
-
}
|
|
862
|
-
else if (atom.value.type === AuxOpType.Signature) {
|
|
863
|
-
return signatureRemovedAtomReducer(weave, atom, atom.value, state);
|
|
864
|
-
}
|
|
865
|
-
else {
|
|
866
|
-
return state;
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
function valueRemovedAtomReducer(weave, atom, value, state) {
|
|
870
|
-
const [tag, bot] = weave.referenceChain(atom.cause);
|
|
871
|
-
if (!tag || !bot) {
|
|
872
|
-
return state;
|
|
873
|
-
}
|
|
874
|
-
if (bot.atom.value.type !== AuxOpType.Bot) {
|
|
875
|
-
return state;
|
|
876
|
-
}
|
|
877
|
-
if (tag.atom.value.type !== AuxOpType.Tag) {
|
|
878
|
-
return state;
|
|
879
|
-
}
|
|
880
|
-
if (!hasValue(tag.atom.value.name)) {
|
|
881
|
-
return state;
|
|
882
|
-
}
|
|
883
|
-
const isDeleted = isBotDeleted(bot);
|
|
884
|
-
if (isDeleted) {
|
|
885
|
-
return state;
|
|
886
|
-
}
|
|
887
|
-
const tagName = tag.atom.value.name;
|
|
888
|
-
const id = bot.atom.value.id;
|
|
889
|
-
const firstValue = first(iterateCausalGroup(tag));
|
|
890
|
-
if (firstValue &&
|
|
891
|
-
firstValue.atom.value.type === AuxOpType.Value &&
|
|
892
|
-
firstValue.atom.hash !== atom.hash) {
|
|
893
|
-
if (firstValue.atom.id.timestamp <= atom.id.timestamp) {
|
|
894
|
-
// The atom was removed so and the first atom
|
|
895
|
-
// happened before it so it should have the new value.
|
|
896
|
-
lodashMerge(state, {
|
|
897
|
-
[id]: {
|
|
898
|
-
tags: {
|
|
899
|
-
[tagName]: firstValue.atom.value.value,
|
|
900
|
-
},
|
|
901
|
-
},
|
|
902
|
-
});
|
|
903
|
-
return state;
|
|
904
|
-
}
|
|
905
|
-
else {
|
|
906
|
-
// The atom was removed but the first atom
|
|
907
|
-
// after it so nothing needs to change.
|
|
908
|
-
return state;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
// If there are no value atoms left, then the new value
|
|
912
|
-
// is null
|
|
913
|
-
lodashMerge(state, {
|
|
914
|
-
[id]: {
|
|
915
|
-
tags: {
|
|
916
|
-
[tagName]: null,
|
|
917
|
-
},
|
|
918
|
-
},
|
|
919
|
-
});
|
|
920
|
-
return state;
|
|
921
|
-
}
|
|
922
|
-
function certificateRemovedAtomReducer(weave, atom, value, node, state) {
|
|
923
|
-
const id = certificateId(atom);
|
|
924
|
-
lodashMerge(state, {
|
|
925
|
-
[id]: null,
|
|
926
|
-
});
|
|
927
|
-
for (let child of iterateCausalGroup(node)) {
|
|
928
|
-
if (child.atom.value.type === AuxOpType.Certificate) {
|
|
929
|
-
certificateRemovedAtomReducer(weave, child.atom, child.atom.value, child, state);
|
|
930
|
-
}
|
|
931
|
-
else if (child.atom.value.type === AuxOpType.Signature) {
|
|
932
|
-
signatureRemovedAtomReducer(weave, child.atom, child.atom.value, state);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
return state;
|
|
936
|
-
}
|
|
937
|
-
function signatureRemovedAtomReducer(weave, atom, value, state) {
|
|
938
|
-
const [val, tag, bot] = weave.referenceChain(value.valueId);
|
|
939
|
-
if (!val || !tag || !bot) {
|
|
940
|
-
return state;
|
|
941
|
-
}
|
|
942
|
-
if (val.atom.hash !== value.valueHash) {
|
|
943
|
-
return state;
|
|
944
|
-
}
|
|
945
|
-
if (val.atom.value.type !== AuxOpType.Value) {
|
|
946
|
-
return state;
|
|
947
|
-
}
|
|
948
|
-
if (tag.atom.value.type !== AuxOpType.Tag) {
|
|
949
|
-
return state;
|
|
950
|
-
}
|
|
951
|
-
if (bot.atom.value.type !== AuxOpType.Bot) {
|
|
952
|
-
return state;
|
|
953
|
-
}
|
|
954
|
-
const hash = tagValueHash(bot.atom.value.id, tag.atom.value.name, val.atom.value.value);
|
|
955
|
-
lodashMerge(state, {
|
|
956
|
-
[bot.atom.value.id]: {
|
|
957
|
-
signatures: {
|
|
958
|
-
[hash]: null,
|
|
959
|
-
},
|
|
960
|
-
},
|
|
961
|
-
});
|
|
962
|
-
return state;
|
|
963
|
-
}
|
|
964
|
-
function revocationRemovedAtomReducer(weave, atom, value, state) {
|
|
965
|
-
if (!atom.cause) {
|
|
966
|
-
return state;
|
|
967
|
-
}
|
|
968
|
-
const parent = weave.getNode(atom.cause);
|
|
969
|
-
if (!parent) {
|
|
970
|
-
return state;
|
|
971
|
-
}
|
|
972
|
-
if (parent.atom.value.type === AuxOpType.Certificate) {
|
|
973
|
-
return certificateAtomAddedReducer(weave, parent.atom, parent.atom.value, state);
|
|
974
|
-
}
|
|
975
|
-
return state;
|
|
976
|
-
}
|
|
977
|
-
export function certificateId(atom) {
|
|
978
|
-
return uuidv5(atom.hash, CERT_ID_NAMESPACE);
|
|
979
|
-
}
|
|
980
|
-
//# sourceMappingURL=AuxWeaveReducer.js.map
|