Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

colyseus-events

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

colyseus-events - npm Package Compare versions

Comparing version 1.1.0 to 2.0.0

29

dist/index.d.ts
import { ArraySchema, CollectionSchema, MapSchema, Schema, SetSchema } from '@colyseus/schema';
export declare type Primitive = number | string | boolean;
export declare type Primitive = number | string | boolean | null | undefined;
export declare type Container = Schema | ArraySchema | MapSchema | CollectionSchema | SetSchema;
export declare type Colyseus = Primitive | Container;
export interface Events<E = string> {
emit(event: E, ...values: unknown[]): unknown;
on(event: E, fn: (...values: unknown[]) => unknown): unknown;
emit(eventName: E, value: Event): unknown;
}
export declare type Add = {
op: 'add';
path: string;
value: Colyseus;
};
export declare type Replace = {
op: 'replace';
path: string;
value: Colyseus;
};
export declare type Remove = {
op: 'remove';
path: string;
};
export declare type Event = Add | Remove | Replace;
export declare function add(path: string, value: Colyseus): Add;
export declare function replace(path: string, value: Colyseus): Replace;
export declare function remove(path: string): Remove;
/**
* make every change in Colyseus state trigger an event in the EventEmitter using the provided namespace.
* @param state Colyseus state to track
* @param events EventsEmitter of you choice. has to support `emit()` and `on()`
* @param namespace Prefix of events name to emit
* @returns the provided events emitter
* @param events EventsEmitter of you choice. has to at least have the method `emit(eventName, value)`.
* @param namespace (optional) Prefix of json pointer
* @returns the provided events emitter (2nd argument)
*/
export declare function wireEvents<T extends Events>(state: Colyseus, events: T, namespace?: string): T;
//# sourceMappingURL=index.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wireEvents = void 0;
exports.wireEvents = exports.remove = exports.replace = exports.add = void 0;
const schema_1 = require("@colyseus/schema");

@@ -10,8 +10,20 @@ const schemaKeys = Object.keys(new (class extends schema_1.Schema {

}
function add(path, value) {
return { op: 'add', path, value };
}
exports.add = add;
function replace(path, value) {
return { op: 'replace', path, value };
}
exports.replace = replace;
function remove(path) {
return { op: 'remove', path };
}
exports.remove = remove;
/**
* make every change in Colyseus state trigger an event in the EventEmitter using the provided namespace.
* @param state Colyseus state to track
* @param events EventsEmitter of you choice. has to support `emit()` and `on()`
* @param namespace Prefix of events name to emit
* @returns the provided events emitter
* @param events EventsEmitter of you choice. has to at least have the method `emit(eventName, value)`.
* @param namespace (optional) Prefix of json pointer
* @returns the provided events emitter (2nd argument)
*/

@@ -25,6 +37,5 @@ function wireEvents(state, events, namespace = '') {

for (const { field, value } of changes) {
const fieldNamespace = namespace ? `${namespace}.${field}` : field;
events.emit(fieldNamespace, value, fieldNamespace);
//@ts-ignore : the field is legal for the state
wireEvents(state[field], events, fieldNamespace);
const fieldNamespace = `${namespace}/${field}`;
events.emit(fieldNamespace, replace(fieldNamespace, value));
wireEvents(value, events, fieldNamespace);
}

@@ -34,5 +45,5 @@ };

if (!schemaKeys.includes(field) && Object.prototype.hasOwnProperty.call(state, field)) {
const fieldNamespace = namespace ? `${namespace}.${field}` : field;
//@ts-ignore : the field is legal for the state
wireEvents(state[field], events, fieldNamespace);
const fieldNamespace = `${namespace}/${field}`;
const value = state[field];
wireEvents(value, events, fieldNamespace);
}

@@ -42,13 +53,18 @@ }

else if (state instanceof schema_1.ArraySchema) {
state.onAdd = state.onChange = (value, field) => {
const fieldNamespace = `${namespace}[${field}]`;
events.emit(fieldNamespace, value, fieldNamespace);
state.onAdd = (value, field) => {
const fieldNamespace = `${namespace}/${field}`;
events.emit(namespace, add(fieldNamespace, value));
wireEvents(value, events, fieldNamespace);
};
state.onChange = (value, field) => {
const fieldNamespace = `${namespace}/${field}`;
events.emit(fieldNamespace, replace(fieldNamespace, value));
wireEvents(value, events, fieldNamespace);
};
state.onRemove = (_, field) => {
const fieldNamespace = `${namespace}[${field}]`;
events.emit(fieldNamespace, undefined, fieldNamespace);
const fieldNamespace = `${namespace}/${field}`;
events.emit(namespace, remove(fieldNamespace));
};
for (const [field, value] of state.entries()) {
const fieldNamespace = `${namespace}[${field}]`;
const fieldNamespace = `${namespace}/${field}`;
wireEvents(value, events, fieldNamespace);

@@ -58,13 +74,18 @@ }

else if (state instanceof schema_1.MapSchema) {
state.onAdd = state.onChange = (value, field) => {
const fieldNamespace = `${namespace}["${field}"]`;
events.emit(fieldNamespace, value, fieldNamespace);
state.onAdd = (value, field) => {
const fieldNamespace = `${namespace}/${field}`;
events.emit(namespace, add(fieldNamespace, value));
wireEvents(value, events, fieldNamespace);
};
state.onChange = (value, field) => {
const fieldNamespace = `${namespace}/${field}`;
events.emit(fieldNamespace, replace(fieldNamespace, value));
wireEvents(value, events, fieldNamespace);
};
state.onRemove = (_, field) => {
const fieldNamespace = `${namespace}["${field}"]`;
events.emit(fieldNamespace, undefined, fieldNamespace);
const fieldNamespace = `${namespace}/${field}`;
events.emit(namespace, remove(fieldNamespace));
};
for (const [field, value] of state.entries()) {
const fieldNamespace = `${namespace}["${field}"]`;
const fieldNamespace = `${namespace}/${field}`;
wireEvents(value, events, fieldNamespace);

@@ -71,0 +92,0 @@ }

{
"name": "colyseus-events",
"version": "1.1.0",
"version": "2.0.0",
"description": "generate notification events from colyseus state",

@@ -5,0 +5,0 @@ "repository": "git@github.com:starwards/colyseus-events.git",

# colyseus-events
generate notification events from colyseus state. forked from https://github.com/amir-arad/colyseus-mobx
Generate json-patch events from colyseus state.
```typescript
import { wireEvents } from 'colyseus-events';
const room: Room<GameState> = await client.joinOrCreate("game");
const events = wireEvents(room.state, new EventEmitter());
// `events` will emit json-patch events whenever the room state changes
```

@@ -11,3 +17,3 @@ ## version support

The schema types new to Colyseus 0.14 (`CollectionSchema` and `SetSchema`) are not yet supported. please open an issue if you would like to use them.
The schema types new to Colyseus 0.14 (`CollectionSchema` and `SetSchema`) are not yet supported. please open an issue if you would like to see them supported.

@@ -23,12 +29,41 @@ ## Installation

const events = wireEvents(room.state, new EventEmitter());
// `events` will emit json-patch events whenever the room state changes
```
then you can wire listeners to `events` and start triggering them.
then you can wire listeners to `events` using their [JSON-pointer](https://github.com/janl/node-jsonpointer) as event name.
whenever something changes in the state, an event will be emitted immediately. the name of the event will be the path of the changed property (or element). The event value will be the new value of that property or element. for convenience, the second value will be the event name. this can be helpful for listeners thatregister for more that one property.
## Examples
examples:
when the server executes: `room.state.foo.bar = 15` event `'foo.bar'` will be emitted with values `15` and `'foo.bar'`.
when the server executes: `room.state.foo.bar.push(15)` event `'foo.bar[0]'` will be emitted with values `15` and `'foo.bar[0]'`.
For example, given the room state:
```typescript
export class Inner extends Schema {
@type('uint8') public baz = 0;
}
export class GameState extends Schema {
@type('uint8') public foo = 0;
@type(Inner) public bar = new Inner();
@type(['uint8']) public numbersArray = new ArraySchema<number>();
@type({ map: 'uint8' }) public mapNumbers = new MapSchema<number>();
}
```
### changing values
when changing a value in Schema or collection (ArraySchema or MapSchema), an event will be emitted. The name of the event will be the [JSON-pointer](https://github.com/janl/node-jsonpointer) describing the location of the property. The event value will be a ["replace" JSON Patch](https://jsonpatch.com/#replace) corresponding with the change.
For example:
- when the server executes: `room.state.foo = 1` an event named `'/foo'` will be emitted with value `{ op: 'replace', path: '/foo', value: 1 }`
- when the server executes: `room.numbersArray[0] = 1` (assuming numbersArray had a previous value at index 0) an event named `'/numbersArray/1'` will be emitted with value `{ op: 'replace', path: '/numbersArray/1', value: 1 }`
- when the server executes: `room.mapNumbers.set('F00', 1)` (assuming mapNumbers had a previous value at key `F00`) an event named `'/mapNumbers/F00'` will be emitted with value `{ op: 'replace', path: '/mapNumbers/F00', value: 1 }`
- when the server executes: `room.state.bar.baz = 1` an event named `'/bar/baz'` will be emitted with value `{ op: 'replace', path: '/bar/baz', value: 1 }`
- when the server executes: `room.state.bar = new Inner()` an event named `'/bar'` will be emitted with value `{ op: 'replace', path: '/bar', value: {{the actual object in state.bar }} }`
...and so on.
### adding and removing elements in collections
when adding or removing elements in a collection (ArraySchema or MapSchema), an event will be also be emitted. The name of the event will be the [JSON-pointer](https://github.com/janl/node-jsonpointer) describing the location of the **container**. The event value will be a ["add"](https://jsonpatch.com/#add) or ["remove"](https://jsonpatch.com/#remove) JSON Patch corresponding with the change. the `path` in the event value will point to the location of the **element** that was added or removed.
For example:
- when the server executes: `room.numbersArray.push(1)` an event named `'/numbersArray'` will be triggered with value `{ op: 'add', path: '/numbersArray/0', value: 1 }`
- when the server executes: `room.numbersArray.pop()` an event named `'/numbersArray'` will be triggered with value `{ op: 'remove', path: '/numbersArray/0' }`
- when the server executes: `room.mapNumbers.set('F00', 1)` an event named `'/mapNumbers'` will be triggered with value `{ op: 'add', path: '/mapNumbers/F00', value: 1 }`
- when the server executes: `room.mapNumbers.delete('F00')` an event named `'/mapNumbers'` will be triggered with value `{ op: 'remove', path: '/mapNumbers/F00' }`
...and so on.
You are welcomed to explore the tests in the github repo for more examples.
## Contributor instructions

@@ -35,0 +70,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc