playhtml 2.1.12 → 2.2.1
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/README.md +57 -0
- package/dist/main.d.ts +49 -17
- package/dist/playhtml.es.js +3052 -2077
- package/dist/style.css +1 -1
- package/package.json +15 -5
- package/CHANGELOG.md +0 -88
package/README.md
CHANGED
|
@@ -181,6 +181,59 @@ The only required properties are `defaultData`, `updateElement` and some kind of
|
|
|
181
181
|
|
|
182
182
|
If you make something fun, please show me! This is designed as an open library for anyone to add on new interactions and capabilities, so we [welcome contributions](https://github.com/spencerc99/playhtml/blob/main/CONTRIBUTING.md) for new built-in capabilities.
|
|
183
183
|
|
|
184
|
+
#### Data updates: mutator vs replacement
|
|
185
|
+
|
|
186
|
+
playhtml supports two ways to update an element's `data` via `setData`, and they have different semantics:
|
|
187
|
+
|
|
188
|
+
- **Mutator form**: pass a function that receives a draft and mutate it in place. This is merge-friendly (supports adding to a list without conflicts) and is the recommended way to update nested arrays/objects.
|
|
189
|
+
- **Replacement form**: pass a full value. This replaces the entire snapshot and is useful for canonical state.
|
|
190
|
+
|
|
191
|
+
Examples
|
|
192
|
+
|
|
193
|
+
1. **Mutator (merge-friendly): append to a list**
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
// data: { messages: string[] }
|
|
197
|
+
setData((draft) => {
|
|
198
|
+
draft.messages.push("hello");
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Note: when working with the mutator forms, there are some limitations on how you can mutate the array properly.
|
|
203
|
+
**✅ Supported Array Operations:**
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
setData((draft) => {
|
|
207
|
+
// ✅ Adding elements
|
|
208
|
+
draft.items.push(newItem);
|
|
209
|
+
|
|
210
|
+
// ✅ Removing/inserting at specific positions
|
|
211
|
+
draft.items.splice(0, 1); // Remove first element
|
|
212
|
+
draft.items.splice(2, 0, newItem); // replace element at index 2
|
|
213
|
+
|
|
214
|
+
// ✅ Modifying existing objects in the array
|
|
215
|
+
draft.items[0].name = "updated";
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**❌ Unsupported Array Operations:**
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
setData((draft) => {
|
|
223
|
+
// ❌ These will throw "array assignment is not implemented / supported"
|
|
224
|
+
draft.items.shift(); // Use splice(0, 1) instead
|
|
225
|
+
draft.items.pop(); // Use splice(-1, 1) instead
|
|
226
|
+
draft.items[index] = newItem; // Use splice(index, 1, newItem) instead
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
2. **Replacement (overwrite snapshot): toggle boolean**
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
// data: { on: boolean; ... }
|
|
234
|
+
setData({ ...data, on: !data.on });
|
|
235
|
+
```
|
|
236
|
+
|
|
184
237
|
### Advanced
|
|
185
238
|
|
|
186
239
|
IDs are recommended on all elements to uniquely identify them. If you are applying the same capability to several elements, you can also use the `selector-id` attribute to specify a selector to the elements that distinguishes them. The ID will be the index of the element in that selector query.
|
|
@@ -244,3 +297,7 @@ See [CONTRIBUTING.md](https://github.com/spencerc99/playhtml/blob/main/CONTRIBUT
|
|
|
244
297
|
## Support & Maintenance
|
|
245
298
|
|
|
246
299
|
Thank you for considering reading this little README and browing this project! I'd love to see you share the library and what you've made with it to me and with your friends. And if you enjoy using this, please consider [sponsoring the project or sending a small donation](https://github.com/sponsors/spencerc99). This helps ensure that the library is maintained and improved over time and funds the hosting costs for the syncing and persistence services.
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
```
|
package/dist/main.d.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { ModifierKey } from '
|
|
10
|
-
import { PlayEvent } from '
|
|
11
|
-
import { RegisteredPlayEvent } from '
|
|
12
|
-
import { TagType } from '
|
|
1
|
+
import { default as default_2 } from 'y-partykit/provider';
|
|
2
|
+
import { ElementAwarenessEventHandlerData } from '../../common/src';
|
|
3
|
+
import { ElementData } from '../../common/src';
|
|
4
|
+
import { ElementEventHandlerData } from '../../common/src';
|
|
5
|
+
import { ElementInitializer } from '../../common/src';
|
|
6
|
+
import { ElementSetupData } from '../../common/src';
|
|
7
|
+
import { EventMessage } from '../../common/src';
|
|
8
|
+
import { MappedTypeDescription } from '@syncedstore/core/types/doc';
|
|
9
|
+
import { ModifierKey } from '../../common/src';
|
|
10
|
+
import { PlayEvent } from '../../common/src';
|
|
11
|
+
import { RegisteredPlayEvent } from '../../common/src';
|
|
12
|
+
import { TagType } from '../../common/src';
|
|
13
13
|
import * as Y from 'yjs';
|
|
14
|
-
import YPartyKitProvider from 'y-partykit/provider';
|
|
15
14
|
|
|
16
15
|
declare function dispatchPlayEvent(message: EventMessage): void;
|
|
17
16
|
|
|
@@ -49,9 +48,29 @@ declare class ElementHandler<T = any, U = any, V = any> {
|
|
|
49
48
|
getAwarenessEventHandlerData(): ElementAwarenessEventHandlerData<T, U, V>;
|
|
50
49
|
getSetupData(): ElementSetupData<T, U>;
|
|
51
50
|
/**
|
|
52
|
-
* Public
|
|
51
|
+
* Public setter for element data.
|
|
52
|
+
*
|
|
53
|
+
* Semantics:
|
|
54
|
+
* - Mutator form: setData((draft) => { ... })
|
|
55
|
+
* When data is backed by SyncedStore/Yjs (dataMode = "syncedstore"),
|
|
56
|
+
* the draft is a live CRDT proxy. You can mutate nested arrays/objects
|
|
57
|
+
* and the change will be merged across clients without conflicts.
|
|
58
|
+
* Example:
|
|
59
|
+
* setData(d => { d.list.push(item); });
|
|
60
|
+
*
|
|
61
|
+
* - Value form: setData(value)
|
|
62
|
+
* Replaces the entire data snapshot. Use this when you need canonical
|
|
63
|
+
* replacement semantics (e.g., snapshot from a mirror) or when running
|
|
64
|
+
* in legacy plain mode. Example:
|
|
65
|
+
* setData({ on: true });
|
|
66
|
+
*
|
|
67
|
+
* Notes:
|
|
68
|
+
* - In plain mode, only the value form results in a sync; mutating draft
|
|
69
|
+
* is a no-op. Prefer the mutator form for merge-friendly edits.
|
|
70
|
+
* - Directly mutating eventData.data may work in SyncedStore mode, but the
|
|
71
|
+
* recommended portable pattern is setData(draft => { ... }).
|
|
53
72
|
*/
|
|
54
|
-
setData(data: T): void;
|
|
73
|
+
setData(data: T | ((draft: T) => void)): void;
|
|
55
74
|
setMyAwareness(data: V): void;
|
|
56
75
|
setDataDebounced(data: T): void;
|
|
57
76
|
/**
|
|
@@ -60,6 +79,8 @@ declare class ElementHandler<T = any, U = any, V = any> {
|
|
|
60
79
|
reset(): void;
|
|
61
80
|
}
|
|
62
81
|
|
|
82
|
+
declare let globalData: Y.Map<any>;
|
|
83
|
+
|
|
63
84
|
export declare interface InitOptions<T = any> {
|
|
64
85
|
/**
|
|
65
86
|
* The room to connect users to (this should be a string that matches the other users
|
|
@@ -98,9 +119,13 @@ export declare interface InitOptions<T = any> {
|
|
|
98
119
|
* Runs if playhtml fails to connect. Useful to show error messages and debugging.
|
|
99
120
|
*/
|
|
100
121
|
onError?: () => void;
|
|
122
|
+
/**
|
|
123
|
+
* If true, will render some helpful development UI.
|
|
124
|
+
*/
|
|
125
|
+
developmentMode?: boolean;
|
|
101
126
|
}
|
|
102
127
|
|
|
103
|
-
declare function initPlayHTML({ host, extraCapabilities, events, defaultRoomOptions, room: inputRoom, onError, }?: InitOptions): Promise<
|
|
128
|
+
declare function initPlayHTML({ host, extraCapabilities, events, defaultRoomOptions, room: inputRoom, onError, developmentMode, }?: InitOptions): Promise<default_2 | undefined>;
|
|
104
129
|
|
|
105
130
|
export declare const playhtml: PlayHTMLComponents;
|
|
106
131
|
|
|
@@ -110,7 +135,8 @@ declare interface PlayHTMLComponents {
|
|
|
110
135
|
setupPlayElement: typeof setupPlayElement;
|
|
111
136
|
removePlayElement: typeof removePlayElement;
|
|
112
137
|
setupPlayElementForTag: typeof setupPlayElementForTag;
|
|
113
|
-
|
|
138
|
+
syncedStore: (typeof store)["play"];
|
|
139
|
+
globalData: typeof globalData;
|
|
114
140
|
elementHandlers: Map<string, Map<string, ElementHandler>> | undefined;
|
|
115
141
|
eventHandlers: Map<string, Array<RegisteredPlayEvent>> | undefined;
|
|
116
142
|
dispatchPlayEvent: typeof dispatchPlayEvent;
|
|
@@ -148,4 +174,10 @@ declare function setupPlayElement(element: Element, { ignoreIfAlreadySetup }?: {
|
|
|
148
174
|
*/
|
|
149
175
|
declare function setupPlayElementForTag<T extends TagType | string>(element: HTMLElement, tag: T): Promise<void>;
|
|
150
176
|
|
|
177
|
+
declare const store: MappedTypeDescription<StoreShape>;
|
|
178
|
+
|
|
179
|
+
declare type StoreShape = {
|
|
180
|
+
play: Record<string, Record<string, any>>;
|
|
181
|
+
};
|
|
182
|
+
|
|
151
183
|
export { }
|