topazcube 0.0.1 → 0.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "topazcube",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "TopazCube is a real-time collaborative document editing, and multiplayer game library.",
5
5
  "author": "László Matuska @BitOfGold",
6
6
  "license": "Apache-2.0",
@@ -14,10 +14,9 @@
14
14
  },
15
15
  "files": [
16
16
  "src",
17
- "test",
17
+ "dist",
18
18
  "LICENSE",
19
- "README.md",
20
- "package.json"
19
+ "README.md"
21
20
  ],
22
21
  "keywords": [
23
22
  "multiplayer",
@@ -33,8 +32,8 @@
33
32
  ],
34
33
  "sideEffects": false,
35
34
  "exports": {
36
- "import": "./dist/topazcube.mjs",
37
- "require": "./dist/topazcube.js"
35
+ "import": "./dist/topazcube.js",
36
+ "require": "./dist/topazcube.cjs"
38
37
  },
39
38
  "type": "module",
40
39
  "scripts": {
@@ -43,8 +42,7 @@
43
42
  "preview": "vite preview --host 0.0.0.0 --port 8800"
44
43
  },
45
44
  "devDependencies": {
46
- "vite": "^6.2.0",
47
- "vite-plugin-glsl": "^1.3.3"
45
+ "vite": "^6.2.0"
48
46
  },
49
47
  "dependencies": {
50
48
  "@msgpack/msgpack": "^3.1.0",
@@ -1,224 +0,0 @@
1
- import React, { useEffect, useState } from "react"
2
- import TopazCubeClient from "../../src/client.js"
3
- import "./index.css"
4
- import { GripHorizontal, Trash2 } from "lucide-react"
5
-
6
- function App() {
7
- // Client instance
8
- let [client, setClient] = useState({})
9
- const [isConnected, setIsConnected] = useState(false)
10
-
11
- // Document state (list of todos)
12
- let [doc, setDoc] = useState({})
13
- // Sorted todos by order field
14
- const sortedTodos = doc.todos ? [...doc.todos].filter((todo) => !todo.deleted).sort((a, b) => a.order - b.order) : []
15
-
16
- // New todo input
17
- const [newTodo, setNewTodo] = useState("")
18
-
19
- // For drag and drop reordering
20
- const [draggedItem, setDraggedItem] = useState(null)
21
- const [movingUp, setMovingUp] = useState(false)
22
- const [dragOverIndex, setDragOverIndex] = useState(null)
23
-
24
- // Initialize client
25
- useEffect(() => {
26
- class TodoClient extends TopazCubeClient {
27
- constructor() {
28
- super({
29
- url: "ws://192.168.0.200:4799",
30
- })
31
- }
32
-
33
- onConnect() {
34
- setIsConnected(true)
35
- this.subscribe("todos")
36
- }
37
-
38
- onDisconnect() {
39
- setIsConnected(false)
40
- }
41
-
42
- onMessage(message) {
43
- console.log("orig onMessage", message)
44
- }
45
-
46
- onChange(name) {
47
- console.log('onChange ez', this.document)
48
- setDoc({ ...this.document })
49
- }
50
- }
51
-
52
- let nc = new TodoClient()
53
- setClient(nc)
54
- nc.connect()
55
-
56
- return () => {
57
- nc.destroy()
58
- }
59
- }, [])
60
-
61
- // Add new todo
62
- const addTodo = () => {
63
- if (newTodo) {
64
- doc.todos.push({
65
- title: newTodo,
66
- completed: false,
67
- order: doc.todos.length,
68
- })
69
- setNewTodo("")
70
- }
71
- }
72
-
73
- // Drag and drop handlers
74
-
75
- const handleDragStart = (e, todo, index) => {
76
- setDraggedItem(todo)
77
- e.dataTransfer.effectAllowed = "move"
78
- // Required for Firefox
79
- e.dataTransfer.setData("text/plain", index)
80
- }
81
-
82
- const handleDragOver = (e, overTodo, overIndex) => {
83
- e.preventDefault()
84
- if (!draggedItem || draggedItem === overTodo) return
85
- setDragOverIndex(overIndex)
86
- if (draggedItem.order <= overTodo.order) {
87
- setMovingUp(false)
88
- } else {
89
- setMovingUp(true)
90
- }
91
- }
92
-
93
- const handleDragEnd = () => {
94
- setDraggedItem(null)
95
- setDragOverIndex(null)
96
- }
97
-
98
- const handleDrop = (e, dropTodo) => {
99
- e.preventDefault()
100
- if (!draggedItem || draggedItem === dropTodo) return
101
-
102
- // Get current orders
103
- const currentOrders = sortedTodos.map((todo) => todo.order)
104
-
105
- // Find the current order of dragged and drop items
106
- const draggedOrder = draggedItem.order
107
- const dropOrder = dropTodo.order
108
-
109
- // Reorder the items
110
- if (draggedOrder < dropOrder) {
111
- // Moving down
112
- doc.todos.forEach((todo) => {
113
- if (todo === draggedItem) {
114
- todo.order = dropOrder
115
- } else if (todo.order > draggedOrder && todo.order <= dropOrder) {
116
- todo.order--
117
- }
118
- })
119
- } else {
120
- // Moving up
121
- doc.todos.forEach((todo) => {
122
- if (todo === draggedItem) {
123
- todo.order = dropOrder
124
- } else if (todo.order >= dropOrder && todo.order < draggedOrder) {
125
- todo.order++
126
- }
127
- })
128
- }
129
-
130
- setDoc({ ...doc })
131
- setDraggedItem(null)
132
- setDragOverIndex(null)
133
- }
134
-
135
- return (
136
- <>
137
- <div className="mx-auto w-full md:max-w-2xl p-2">
138
- <h1>TopazCube Client Test</h1>
139
- <h2>Todo list: '{doc.title}'</h2>
140
- {sortedTodos.length > 0 ? (
141
- <div>
142
- <ul>
143
- {sortedTodos.map(
144
- (todo, index) =>
145
- !todo.deleted && (
146
- <li
147
- key={index}
148
- className={`flex items-center gap-2 py-1
149
- ${index % 2 == 0 ? "bg-gray-200" : ""} ${
150
- dragOverIndex === index ? "border-" + (movingUp ? "t" : "b") + "-3 border-blue-500" : ""
151
- }`}
152
- draggable={true}
153
- onDragStart={(e) => handleDragStart(e, todo)}
154
- onDragOver={(e) => handleDragOver(e, todo, index)}
155
- onDragEnd={handleDragEnd}
156
- onDrop={(e) => handleDrop(e, todo)}>
157
- <button className="!cursor-move">
158
- <GripHorizontal />
159
- </button>
160
- <input
161
- type="checkbox"
162
- className="cursor-pointer w-5 h-5"
163
- checked={todo.completed}
164
- onChange={() => {
165
- todo.completed = !todo.completed
166
- }}
167
- />
168
- <span className="flex-grow ml-2 cursor-move">
169
- <span className={`${todo.completed ? "line-through opacity-30" : "font-bold"} cursor-text`}>
170
- {todo.title}
171
- </span>
172
- </span>
173
- <button
174
- onClick={() => {
175
- todo.deleted = true
176
- }}>
177
- <Trash2 />
178
- </button>
179
- </li>
180
- )
181
- )}
182
- </ul>
183
- </div>
184
- ) : (
185
- <p>No todos yet. Add some!</p>
186
- )}
187
- <br />
188
- <div className="flex gap-2">
189
- <input
190
- type="text"
191
- className="flex-grow border-2 border-gray-400 px-2 py-1 rounded-md"
192
- placeholder="New Todo"
193
- value={newTodo}
194
- onChange={(e) => setNewTodo(e.target.value)}
195
- />
196
- <button
197
- className={`bg-gray-300 ${
198
- newTodo ? "text-black" : "text-gray-400 opacity-50 !cursor-not-allowed"
199
- } font-bold border-2 border-gray-400 px-4 py-2 rounded-md`}
200
- onClick={addTodo}
201
- onKeyDown={(e) => {
202
- if (e.key === "Enter") {
203
- addTodo()
204
- }
205
- }}>
206
- Add Todo
207
- </button>
208
- </div>
209
- <br />
210
- <pre>{JSON.stringify(doc, null, 2)}</pre>
211
- <br />
212
- </div>
213
- {!isConnected ? (
214
- <div className="fixed inset-0 bg-black/70 flex items-center justify-center z-50">
215
- <h2 className="text-white text-xl font-bold">Connecting...</h2>
216
- </div>
217
- ) : (
218
- <></>
219
- )}
220
- </>
221
- )
222
- }
223
-
224
- export default App
@@ -1,13 +0,0 @@
1
- @import "tailwindcss";
2
-
3
- h1 {
4
- @apply text-2xl font-bold pb-4;
5
- }
6
-
7
- h2 {
8
- @apply text-xl font-bold pb-2;
9
- }
10
-
11
- button {
12
- @apply transition-all duration-300 font-bold px-2 py-1 rounded-md hover:opacity-50 hover:scale-115 cursor-pointer;
13
- }
@@ -1,13 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>TopazCube Client Test</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script type="module" src="main.jsx"></script>
12
- </body>
13
- </html>
@@ -1,7 +0,0 @@
1
- import React from 'react'
2
- import { createRoot } from 'react-dom/client';
3
- import App from './App'
4
-
5
- const root = createRoot(document.getElementById('root'))
6
- root.render(<App />)
7
-
@@ -1,24 +0,0 @@
1
- {
2
- "name": "topazcube-test-client",
3
- "private": true,
4
- "version": "0.0.1",
5
- "type": "module",
6
- "scripts": {
7
- "dev": "vite --host 0.0.0.0 --port 4800"
8
- },
9
- "devDependencies": {
10
- "vite": "^6.2.0"
11
- },
12
- "dependencies": {
13
- "@msgpack/msgpack": "^3.1.0",
14
- "@tailwindcss/vite": "^4.0.9",
15
- "@vitejs/plugin-react": "^4.3.4",
16
- "collections": "^5.1.13",
17
- "fast-json-patch": "^3.1.1",
18
- "lucide-react": "^0.476.0",
19
- "react": "^19.0.0",
20
- "react-dom": "^19.0.0",
21
- "tailwindcss": "^4.0.9",
22
- "ws": "^8.18.1"
23
- }
24
- }
@@ -1,10 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import tailwindcss from '@tailwindcss/vite'
3
- import react from '@vitejs/plugin-react';
4
-
5
- export default defineConfig({
6
- plugins: [
7
- react(),
8
- tailwindcss(),
9
- ],
10
- })
@@ -1,19 +0,0 @@
1
- {
2
- "name": "topazcube-test-server",
3
- "private": true,
4
- "version": "0.0.1",
5
- "type": "module",
6
- "scripts": {
7
- "dev": "reset && nodemon todoserver.js"
8
- },
9
- "devDependencies": {
10
- "vite": "^6.2.0"
11
- },
12
- "dependencies": {
13
- "@msgpack/msgpack": "^3.1.0",
14
- "collections": "^5.1.13",
15
- "fast-json-patch": "^3.1.1",
16
- "mongodb": "^6.15.0",
17
- "ws": "^8.18.1"
18
- }
19
- }
@@ -1,33 +0,0 @@
1
- import TopazCubeServer from "../../src/server.js"
2
-
3
- class TodoServer extends TopazCubeServer {
4
- constructor() {
5
- super({
6
- port: 4799,
7
- })
8
- }
9
-
10
- canCreate(client, name) {
11
- return true;
12
- }
13
-
14
- onCreate(name) {
15
- return {
16
- todos: [],
17
- }
18
- }
19
-
20
- canUpdate(client, name) {
21
- return true;
22
- }
23
-
24
- onHydrate(name, doc) {
25
- doc.random = Math.random()
26
- }
27
- onUpdate(name, doc, dt) {}
28
- onMessage(client, message) {}
29
-
30
-
31
- }
32
-
33
- let server = new TodoServer()