Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Eventually consistent multiplayer 🤝 #2296

Draft
wants to merge 73 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
d60ff95
WIP: Operational Transform implementation
Pangoraw Sep 25, 2022
1fdf06b
Handle unicode characters and start writing tests
Pangoraw Sep 28, 2022
5339451
remove @show
Pangoraw Sep 28, 2022
a895044
💚 ugly cursor sync
Pangoraw Sep 30, 2022
5099422
Merge branch 'main' into pb/ot
Pangoraw Sep 30, 2022
bb0f7d5
Remove last run version facet
Pangoraw Sep 30, 2022
36c7361
Don't include packages in the tested versionand
Pangoraw Sep 30, 2022
7858481
Update
Pangoraw Sep 30, 2022
66eaab8
Fix tests
Pangoraw Oct 2, 2022
2a6b1c0
fix
Pangoraw Oct 2, 2022
fee51f7
Merge branch 'main' into pb/ot
Pangoraw Oct 4, 2022
510bcf0
Style updates
Pangoraw Sep 5, 2023
13bf264
Merge branch 'main' into pb/ot
Pangoraw Sep 5, 2023
dfaa2c6
Token lock
Pangoraw Sep 5, 2023
9aa5619
Update React.jl
Pangoraw Sep 14, 2023
270ac1b
update 👪﬉
Pangoraw Sep 17, 2023
53b2132
Merge remote-tracking branch 'origin/main' into pb/ot
Pangoraw Sep 30, 2023
8f5869b
remove index.es.js
Pangoraw Sep 30, 2023
f50a001
remove console.log
Pangoraw Sep 30, 2023
1cfe2f9
wip delta
Pangoraw Sep 30, 2023
c0f069a
update
Pangoraw Oct 1, 2023
c961c75
style ✨✨
Pangoraw Oct 1, 2023
cfec15e
Update OperationalTransform.jl
Pangoraw Oct 5, 2023
4a3077d
Merge branch 'main' into pb/ot
Pangoraw Oct 18, 2023
7abd6c5
Merge branch 'main' into pb/ot
Pangoraw Nov 22, 2023
2570e1a
cursors
Pangoraw Nov 22, 2023
a7afa70
cursors 2
Pangoraw Nov 24, 2023
a02ca7f
cursors 3
Pangoraw Nov 24, 2023
6a1ea98
cursors 4
Pangoraw Nov 24, 2023
d45adae
cursors 5
Pangoraw Nov 27, 2023
9880aa1
Merge branch 'main' into pb/ot
Pangoraw Nov 28, 2023
5804545
--wip-- [skip ci]
Pangoraw Oct 7, 2023
2a09f38
--wip-- [skip ci]
Pangoraw Mar 12, 2024
acb6bfb
pinot!!
Pangoraw Mar 12, 2024
b3bfb98
Merge remote-tracking branch 'origin' into pb/ot
Pangoraw Mar 12, 2024
4e9e0dd
remove
Pangoraw Mar 12, 2024
83fb3ae
--wip-- [skip ci]
Pangoraw Mar 26, 2024
c5dba39
pInot2
Pangoraw Mar 26, 2024
6237989
collab: global registration of plugins
Pangoraw Apr 22, 2024
b97a2ad
clean collab module
Pangoraw Apr 22, 2024
2f81799
ok
Pangoraw Apr 22, 2024
70b00f3
Merge remote-tracking branch 'origin' into pb/ot
Pangoraw Apr 22, 2024
29035b3
initialize last_run_code with code
Pangoraw Apr 22, 2024
ad3b581
mouse users and users mouse data
Pangoraw May 8, 2024
7404382
push updates for file watching
Pangoraw May 8, 2024
b03fcd9
remove test files
Pangoraw May 9, 2024
4150cc2
remove ot test files
Pangoraw May 9, 2024
d50fcb8
Merge branch 'main' into pb/ot
Pangoraw May 10, 2024
b4d7383
Merge branch 'main' into pb/ot
Pangoraw May 17, 2024
54f52ef
fix setcode!
Pangoraw May 20, 2024
e8fecc7
co-authorship
Pangoraw May 20, 2024
592d15c
fix 2
Pangoraw May 20, 2024
5b65626
fix 3
Pangoraw May 20, 2024
26ef56d
Update MacroAnalysis.jl
Pangoraw May 21, 2024
52bba32
Update Run.jl
Pangoraw May 21, 2024
1fbca26
Update Run.jl
Pangoraw May 21, 2024
f2c83ab
Update Cell.jl
Pangoraw May 21, 2024
70a331a
cleanup javascript
Pangoraw May 30, 2024
bae10ae
update
Pangoraw May 30, 2024
19329bd
Pass typescript checks
Pangoraw Jun 2, 2024
ab62db2
more stuff
Pangoraw Jun 2, 2024
5bf8323
move info to debug
Pangoraw Jun 2, 2024
11fc0c1
fix cell creation from frontend
Pangoraw Jun 8, 2024
693929a
remove mention of last run version
Pangoraw Jun 8, 2024
331f91b
wrap remote cell
Pangoraw Jun 18, 2024
7838424
remove log
Pangoraw Jun 18, 2024
6cd96d6
more robust code diffing
Pangoraw Jun 18, 2024
76dee4e
remove cell_inputs_local, everything is now managed using codemirror
Pangoraw Jun 18, 2024
fe76128
start work on effect in the server
Pangoraw Jun 18, 2024
e1f5eab
test
Pangoraw Jun 18, 2024
a094d8e
share cursor stuff again and pass through transformations
Pangoraw Jul 11, 2024
c3c2b37
more types
Pangoraw Jul 11, 2024
f1e07e7
Fix test
Pangoraw Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ MIMEs = "6c6e2e6c-3030-632d-7369-2d6c69616d65"
Malt = "36869731-bdee-424d-aa32-cab38c994e3b"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
MsgPack = "99f44e22-a591-53d1-9472-aa23ef4bd671"
Pinot = "14b02da0-8be6-40d8-a4f8-a7d73caed26e"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlutoDependencyExplorer = "72656b73-756c-7461-726b-72656b6b696b"
PrecompileSignatures = "91cefc8d-f054-46dc-8f8c-26e11d7c5411"
Expand Down
17 changes: 16 additions & 1 deletion frontend/components/BottomRightPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ import { is_finished, ProcessTab, total_done, total_tasks, useStatusItem } from
import { useMyClockIsAheadBy } from "../common/clock sync.js"
import { BackendLaunchPhase } from "../common/Binder.js"
import { useEventListener } from "../common/useEventListener.js"
import { CollabTab } from "./CollabTab.js"

/**
* @typedef PanelTabName
* @type {"docs" | "process" | null}
* @type {"docs" | "process" | "collab" | null}
*/

export const open_bottom_right_panel = (/** @type {PanelTabName} */ tab) => window.dispatchEvent(new CustomEvent("open_bottom_right_panel", { detail: tab }))

/**
* @param {{
* notebook: import("./Editor.js").NotebookData,
* client_id: string,
* desired_doc_query: string?,
* on_update_doc_query: (query: string?) => void,
* connected: boolean,
Expand All @@ -27,6 +29,7 @@ export const open_bottom_right_panel = (/** @type {PanelTabName} */ tab) => wind
*/
export let BottomRightPanel = ({
desired_doc_query,
client_id,
on_update_doc_query,
notebook,
connected,
Expand Down Expand Up @@ -56,6 +59,8 @@ export let BottomRightPanel = ({
[set_open_tab]
)

const showMultiplayerTab = notebook.users && Object.keys(notebook.users).some(user_id => user_id != client_id)

const status = useWithBackendStatus(notebook, backend_launch_phase)

const [status_total, status_done] = useMemo(
Expand Down Expand Up @@ -119,6 +124,14 @@ export let BottomRightPanel = ({
: html`Status${" "}<span class="subprogress-counter">(${status_done}/${status_total})</span>`}</span
>
</button>
<button title="Collaboration"
class=${cl({
"helpbox-tab-key": true,
"active": open_tab === "collab",
})}
onClick=${() => set_open_tab(open_tab === "collab" ? null : "collab")}>
<span class="tabname">Collaboration</span>
</button>
${hidden
? null
: html`<button
Expand Down Expand Up @@ -146,6 +159,8 @@ export let BottomRightPanel = ({
my_clock_is_ahead_by=${my_clock_is_ahead_by}
status=${status}
/>`
: open_tab === "collab"
? html`<${CollabTab} client_id=${client_id} notebook=${notebook} />`
: null}
</pluto-helpbox>
</aside>
Expand Down
37 changes: 17 additions & 20 deletions frontend/components/Cell.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,13 @@ const on_jump = (hasBarrier, pluto_actions, cell_id) => () => {
* }} props
* */
export const Cell = ({
cell_input: { cell_id, code, code_folded, metadata },
cell_input: { cell_id, code, code_folded, metadata, cm_updates, start_version, last_run_code },
cell_result: { queued, running, runtime, errored, output, logs, published_object_keys, depends_on_disabled_cells, depends_on_skipped_cells },
cell_dependencies,
cell_input_local,
notebook_id,
client_id,
users,
selected,
force_hide_input,
focus_after_creation,
Expand All @@ -125,19 +127,18 @@ export const Cell = ({
// useCallback because pluto_actions.set_doc_query can change value when you go from viewing a static document to connecting (to binder)
const on_update_doc_query = useCallback((...args) => pluto_actions.set_doc_query(...args), [pluto_actions])
const on_focus_neighbor = useCallback((...args) => pluto_actions.focus_on_neighbor(...args), [pluto_actions])
const on_change = useCallback((val) => pluto_actions.set_local_cell(cell_id, val), [cell_id, pluto_actions])
const variables = useMemo(() => Object.keys(cell_dependencies?.downstream_cells_map ?? {}), [cell_dependencies])

// We need to unmount & remount when a destructive error occurs.
// For that reason, we will use a simple react key and increment it on error
const [key, setKey] = useState(0)
const cell_key = useMemo(() => cell_id + key, [cell_id, key])

const [, resetError] = useErrorBoundary((error) => {
console.log(`An error occured in the CodeMirror code, resetting CellInput component. See error below:\n\n${error}\n\n -------------- `)
setKey(key + 1)
resetError()
})
// const [, resetError] = useErrorBoundary((error) => {
// console.log(`An error occured in the CodeMirror code, resetting CellInput component. See error below:\n\n${error}\n\n -------------- `)
// setKey(key + 1)
// resetError()
// })

const remount = useMemo(() => () => setKey(key + 1))
// cm_forced_focus is null, except when a line needs to be highlighted because it is part of a stack trace
Expand Down Expand Up @@ -204,7 +205,9 @@ export const Cell = ({
// We then toggle animation visibility using opacity. This saves a bunch of repaints.
const activate_animation = useDebouncedTruth(running || queued || waiting_to_run)

const class_code_differs = code !== (cell_input_local?.code ?? code)
const class_code_differs = useMemo(() => (last_run_code !== code), [code, last_run_code])
const class_code_folded = code_folded && cm_forced_focus == null

const no_output_yet = (output?.last_run_timestamp ?? 0) === 0
const code_not_trusted_yet = process_waiting_for_permission && no_output_yet

Expand Down Expand Up @@ -236,17 +239,6 @@ export const Cell = ({
pluto_actions.set_and_run_multiple([cell_id])
}
}, [pluto_actions, cell_id])
const on_change_cell_input = useCallback(
(new_code) => {
if (!disable_input_ref.current) {
if (code_folded && cm_forced_focus != null) {
pluto_actions.fold_remote_cells([cell_id], false)
}
on_change(new_code)
}
},
[code_folded, cm_forced_focus, pluto_actions, on_change]
)
const on_add_after = useCallback(() => {
pluto_actions.add_remote_cell(cell_id, "after")
}, [pluto_actions, cell_id, selected])
Expand Down Expand Up @@ -326,6 +318,10 @@ export const Cell = ({
? html`<${CellOutput} errored=${errored} ...${output} sanitize_html=${sanitize_html} cell_id=${cell_id} />`
: html``}
<${CellInput}
cm_updates=${cm_updates}
code=${code}
start_version=${start_version}
last_run_code=${last_run_code}
local_code=${cell_input_local?.code ?? code}
remote_code=${code}
cell_dependencies=${cell_dependencies}
Expand All @@ -338,13 +334,14 @@ export const Cell = ({
on_submit=${on_submit}
on_delete=${on_delete}
on_add_after=${on_add_after}
on_change=${on_change_cell_input}
on_update_doc_query=${on_update_doc_query}
on_focus_neighbor=${on_focus_neighbor}
on_line_heights=${set_line_heights}
nbpkg=${nbpkg}
cell_id=${cell_id}
notebook_id=${notebook_id}
client_id=${client_id}
users=${users}
metadata=${metadata}
any_logs=${any_logs}
show_logs=${show_logs}
Expand Down
Loading
Loading