Skip to content

Commit

Permalink
Merge branch 'develop' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
DevOps committed Nov 13, 2023
2 parents 6e1c956 + d573c17 commit 4f7dc2f
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 133 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## V3.2.7

#### Date: 11/10/2023
#### Date: 11/13/2023

### :boom: Breaking Changes

Expand Down
3 changes: 1 addition & 2 deletions src/aux-records/PrivoClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,17 +520,16 @@ export class PrivoClient implements PrivoClientInterface {

const data = result.data;

// Privo's email API returns invalid profanity information.
const schema = z.object({
available: z.boolean(),
suggestions: z.array(z.string()).optional(),
profanity: z.boolean().optional(),
});

const validated = schema.parse(data);

return {
available: validated.available,
profanity: validated.profanity,
suggestions: validated.suggestions,
};
}
Expand Down
270 changes: 140 additions & 130 deletions src/aux-server/aux-web/shared/MonacoHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ import {
distinctUntilChanged,
finalize,
} from 'rxjs/operators';
import { Simulation } from '@casual-simulation/aux-vm';
import {
BotTagChange,
BotTagEdit,
BotTagUpdate,
Simulation,
} from '@casual-simulation/aux-vm';
import {
BrowserSimulation,
userBotTagsChanged,
Expand Down Expand Up @@ -1340,147 +1345,152 @@ function watchModel(
let lastVersion = simulation.watcher.latestVersion;
let applyingEdits: boolean = false;

sub.add(
simulation.watcher
.botTagChanged(bot.id, tag, space)
.pipe(
takeWhile((update) => update !== null),
tap((update) => {
lastVersion.vector = mergeVersions(
lastVersion.vector,
update.version
);
}),
filter((update) => {
// Only allow updates that are not edits
// or are not from the current site.
// TODO: Improve to allow edits from the current site to be mixed with
// edits from other sites.
return (
update.type !== 'edit' ||
Object.keys(simulation.watcher.localSites).every(
(site) => !hasValue(update.version[site])
)
);
}),
skip(1)
)
.subscribe((update) => {
bot = update.bot;
if (update.type === 'edit') {
const userSelections = getEditor()?.getSelections() || [];
const selectionPositions = userSelections.map(
(s) =>
[
new monaco.Position(
s.startLineNumber,
s.startColumn
),
new monaco.Position(
s.endLineNumber,
s.endColumn
),
] as [monaco.Position, monaco.Position]
const applyEdit = (update: BotTagEdit) => {
const userSelections = getEditor()?.getSelections() || [];
const selectionPositions = userSelections.map(
(s) =>
[
new monaco.Position(s.startLineNumber, s.startColumn),
new monaco.Position(s.endLineNumber, s.endColumn),
] as [monaco.Position, monaco.Position]
);

for (let ops of update.operations) {
let index = -info.editOffset;
for (let op of ops) {
if (op.type === 'preserve') {
index += op.count;
} else if (op.type === 'insert') {
const pos = model.getPositionAt(index);
const selection = new monaco.Selection(
pos.lineNumber,
pos.column,
pos.lineNumber,
pos.column
);

for (let ops of update.operations) {
let index = -info.editOffset;
for (let op of ops) {
if (op.type === 'preserve') {
index += op.count;
} else if (op.type === 'insert') {
const pos = model.getPositionAt(index);
const selection = new monaco.Selection(
pos.lineNumber,
pos.column,
pos.lineNumber,
pos.column
);

try {
applyingEdits = true;
model.pushEditOperations(
[],
[{ range: selection, text: op.text }],
() => null
);
} finally {
applyingEdits = false;
}
try {
applyingEdits = true;
model.pushEditOperations(
[],
[{ range: selection, text: op.text }],
() => null
);
} finally {
applyingEdits = false;
}

index += op.text.length;

const endPos = model.getPositionAt(index);

offsetSelections(
pos,
endPos,
selectionPositions
);
} else if (op.type === 'delete') {
const startPos = model.getPositionAt(index);
const endPos = model.getPositionAt(
index + op.count
);
const selection = new monaco.Selection(
startPos.lineNumber,
startPos.column,
endPos.lineNumber,
endPos.column
);
try {
applyingEdits = true;
model.pushEditOperations(
[],
[{ range: selection, text: '' }],
() => null
);
} finally {
applyingEdits = false;
}
index += op.text.length;

// Start and end positions are switched
// so that deltas are negative
offsetSelections(
endPos,
startPos,
selectionPositions
);
}
}
}
const endPos = model.getPositionAt(index);

const finalSelections = selectionPositions.map(
([start, end]) =>
new monaco.Selection(
start.lineNumber,
start.column,
end.lineNumber,
end.column
)
offsetSelections(pos, endPos, selectionPositions);
} else if (op.type === 'delete') {
const startPos = model.getPositionAt(index);
const endPos = model.getPositionAt(index + op.count);
const selection = new monaco.Selection(
startPos.lineNumber,
startPos.column,
endPos.lineNumber,
endPos.column
);
getEditor()?.setSelections(finalSelections);
} else {
if (model === activeModel) {
return;
}
let script = getScript(bot, tag, space);
let value = model.getValue();
try {
applyingEdits = true;
if (script !== value) {
model.setValue(script);
}
updateLanguage(
simulation,
model,
tag,
getTagValueForSpace(bot, tag, space),
true
model.pushEditOperations(
[],
[{ range: selection, text: '' }],
() => null
);
} finally {
applyingEdits = false;
}

// Start and end positions are switched
// so that deltas are negative
offsetSelections(endPos, startPos, selectionPositions);
}
}
}

const finalSelections = selectionPositions.map(
([start, end]) =>
new monaco.Selection(
start.lineNumber,
start.column,
end.lineNumber,
end.column
)
);
getEditor()?.setSelections(finalSelections);
};

const applyUpdate = (update: BotTagUpdate) => {
if (model === activeModel) {
return;
}
let script = getScript(bot, tag, space);
let value = model.getValue();
try {
applyingEdits = true;
if (script !== value) {
model.setValue(script);
}
updateLanguage(
simulation,
model,
tag,
getTagValueForSpace(bot, tag, space),
true
);
} finally {
applyingEdits = false;
}
};

const isApplyableChange = (update: BotTagChange) => {
// Only allow updates that are not edits
// or are not from the current site.
// TODO: Improve to allow edits from the current site to be mixed with
// edits from other sites.
return (
update.type !== 'edit' ||
Object.keys(simulation.watcher.localSites).every(
(site) => !hasValue(update.version[site])
)
);
};

sub.add(
simulation.watcher
.botTagChanged(bot.id, tag, space)
.pipe(
skip(1),
takeWhile((update) => update !== null)
)
.subscribe((update) => {
// Ensure that the version vector is updated in the same browser tick
// as applying the update to the editor.
// If we update the version vector and apply the update in separate browser ticks,
// then it is possible for a user edit to get in between the version vector update and the
// update to the editor, which might cause the applied updates to be incorrect.

// Update the version vector
lastVersion.vector = mergeVersions(
lastVersion.vector,
update.version
);

// Check if we can apply the change to the editor
if (!isApplyableChange(update)) {
return;
}

// Apply the change.
bot = update.bot;
if (update.type === 'edit') {
applyEdit(update);
} else {
applyUpdate(update);
}
})
);
Expand Down
2 changes: 2 additions & 0 deletions src/aux-vm-browser/managers/AuthCoordinator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ describe('AuthCoordinator', () => {
privacyFeatures: {
allowPublicData: true,
publishData: true,
allowAI: true,
allowPublicInsts: true,
},
},
};
Expand Down

0 comments on commit 4f7dc2f

Please sign in to comment.