@soundworks/core
Advanced tools
Comparing version 4.0.0-alpha.7 to 4.0.0-alpha.9
{ | ||
"name": "@soundworks/core", | ||
"version": "4.0.0-alpha.7", | ||
"version": "4.0.0-alpha.9", | ||
"description": "Open-source creative coding framework for distributed applications based on Web technologies", | ||
@@ -51,11 +51,11 @@ "authors": [ | ||
"types": "rm -Rf types && tsc", | ||
"version": "npm run toc" | ||
"preversion": "npm run toc && git commit -am 'docs: build' --allow-empty" | ||
}, | ||
"dependencies": { | ||
"@ircam/sc-gettime": "^1.0.0", | ||
"@ircam/sc-utils": "^1.0.1", | ||
"chalk": "^5.2.0", | ||
"@ircam/sc-gettime": "^1.0.1", | ||
"@ircam/sc-utils": "^1.1.1", | ||
"chalk": "^5.3.0", | ||
"columnify": "^1.6.0", | ||
"compression": "^1.7.1", | ||
"cross-fetch": "^3.1.5", | ||
"cross-fetch": "^3.1.8", | ||
"express": "^4.18.1", | ||
@@ -69,3 +69,3 @@ "fast-deep-equal": "^3.1.3", | ||
"lodash.merge": "^4.6.2", | ||
"pem": "^1.14.6", | ||
"pem": "^1.14.8", | ||
"template-literal": "^1.0.4", | ||
@@ -83,5 +83,5 @@ "uuid": "^9.0.0", | ||
"docdash": "^2.0.1", | ||
"dotenv": "^16.0.3", | ||
"eslint": "^8.32.0", | ||
"eslint-plugin-jsdoc": "^40.0.0", | ||
"dotenv": "^16.3.1", | ||
"eslint": "^8.44.0", | ||
"eslint-plugin-jsdoc": "^46.4.3", | ||
"generate-changelog": "^1.8.0", | ||
@@ -91,5 +91,5 @@ "jsdoc": "^4.0.0", | ||
"mocha": "^10.2.0", | ||
"puppeteer": "^19.5.2", | ||
"puppeteer": "^20.7.4", | ||
"tcp-ping": "^0.1.1", | ||
"typescript": "^4.9.3" | ||
"typescript": "^5.1.6" | ||
}, | ||
@@ -96,0 +96,0 @@ "optionalDependencies": { |
@@ -10,3 +10,3 @@ # soundworks | ||
Primarily focused on music, `soundworks` aims at supporting rapid development of real-time distributed applications using _JavaScript_. It provides abstractions to hide the complexity of the network and to foster very rapid-prototyping and trial-and-error workflows that are typical in artistic practices. | ||
Primarily focused on music, **soundworks** aims at supporting rapid development of real-time distributed applications using _JavaScript_. It provides abstractions to hide the complexity of the network and to foster very rapid-prototyping and trial-and-error workflows that are typical in artistic practices. | ||
@@ -17,3 +17,3 @@ *__WARNING: The version 4 of `@soundworks/core` is under heavy development.__* | ||
The best and most simple way to start using `soundworks` is to use the `@soundworks/create` wizard. | ||
The best and most simple way to start using **soundworks** is to use the `@soundworks/create` wizard. | ||
@@ -26,3 +26,3 @@ ```sh | ||
See [https://soundworks.dev/tutorials/getting-started.html](https://soundworks.dev/tutorials/getting-started.html) for more informations on the wizard and how to start with `soundworks`. | ||
See [https://soundworks.dev/tutorials/getting-started.html](https://soundworks.dev/tutorials/getting-started.html) for more informations on the wizard and how to start with **soundworks**. | ||
@@ -51,3 +51,3 @@ <!-- | ||
If you made an application using `soundworks` please let us know here: https://github.com/collective-soundworks/soundworks/discussions/61 | ||
If you made an application using **soundworks** please let us know here: https://github.com/collective-soundworks/soundworks/discussions/61 | ||
@@ -62,3 +62,3 @@ ## TypeScript Support | ||
Note that the `@soundworks/core` package is automatically installed when creating an application using the `@soundworks/create` wizard, so most of the time you should not have to install this package manually. See [https://soundworks.dev/guides/getting-started.html](https://soundworks.dev/guides/getting-started.html) for more informations on the `soundworks` wizard. | ||
Note that the `@soundworks/core` package is automatically installed when creating an application using the `@soundworks/create` wizard, so most of the time you should not have to install this package manually. See [https://soundworks.dev/guides/getting-started.html](https://soundworks.dev/guides/getting-started.html) for more informations on the **soundworks** wizard. | ||
@@ -71,26 +71,7 @@ ``` | ||
`soundworks` has been initiated by [Norbert Schnell](https://github.com/NorbertSchnell), [Sébastien Robaszkiewicz](https://github.com/i-Robi), and [Benjamin Matuszewski](https://github.com/b-ma) at the [ISMM](http://ismm.ircam.fr/) team at [Ircam - Centre Pompidou](http://www.ircam.fr/) in the context of the [CoSiMa](http://cosima.ircam.fr/) research project founded by the French National Research Agency (ANR). | ||
[https://soundworks.dev/credits.html](https://soundworks.dev/credits.html) | ||
Development is now led by Benjamin Matuszewski, in the [Sound Music Movement Interaction Team](https://www.stms-lab.fr/team/interaction-son-musique-mouvement/) from the Ircam's STMS-LAB. | ||
### Supporting Research Projects | ||
Initial and futher developments has been supported by the following research projects: | ||
- The [DOTS](http://dots.ircam.fr/) project, funded by the French National Research Agency (ANR) | ||
- The Ircam projects _BeCoMe_ and _SO(a)P_ | ||
- The _Constella(c)tions_ residency, funded by the STARTS program of the European Commission | ||
- The [RAPID-MIX project](http://rapidmix.goldsmithsdigital.com/), funded by the European Union’s Horizon 2020 research and innovation program | ||
- The [CoSiMa](http://cosima.ircam.fr/) project, funded by the French National Research Agency (ANR) | ||
### Academic Papers | ||
- Benjamin Matuszewski. A Web-Based Framework for Distributed Music System Research and Creation. AES - Journal of the Audio Engineering Society Audio-Accoustics-Application, Audio Engineering Society Inc, 2020. <[hal-03033143](https://hal.archives-ouvertes.fr/hal-03033143)> | ||
- Benjamin Matuszewski. Soundworks - A Framework for Networked Music Systems on the Web - State of Affairs and New Developments. Proceedings of the Web Audio Conference (WAC) 2019, Dec 2019, Trondheim, Norway. <[hal-02387783](https://hal.archives-ouvertes.fr/hal-02387783)> | ||
- Benjamin Matuszewski, Norbert Schnell, Frédéric Bevilacqua. Interaction Topologies in Mobile-Based Situated Networked Music Systems. Wireless Communications and Mobile Computing, Hindawi Publishing Corporation, 2019, 2019, pp.9142490. ⟨10.1155/2019/9142490⟩. <[hal-02086673](https://hal.archives-ouvertes.fr/hal-02086673)> | ||
- Norbert Schnell, Sébastien Robaszkiewicz. Soundworks – A playground for artists and developers to create collaborative mobile web performances. `Proceedings of the Web Audio Conference (WAC'15), 2015, Paris, France. <[hal-01580797](https://hal.archives-ouvertes.fr/hal-01580797)> | ||
## License | ||
[BSD-3-Clause](https://github.com/collective-soundworks/soundworks/blob/master/LICENSE) | ||
[BSD-3-Clause](./LICENSE) | ||
@@ -24,7 +24,9 @@ import { isPlainObject } from '@ircam/sc-utils'; | ||
constructor(id, remoteId, schemaName, schema, client, isOwner, manager, initValues = {}) { | ||
this.id = id; | ||
this.remoteId = remoteId; | ||
this.schemaName = schemaName; | ||
/** @private */ | ||
this._id = id; | ||
/** @private */ | ||
this._remoteId = remoteId; | ||
/** @private */ | ||
this._schemaName = schemaName; | ||
/** @private */ | ||
this._isOwner = isOwner; // may be the server or any client | ||
@@ -36,2 +38,4 @@ /** @private */ | ||
this._detached = false; | ||
try { | ||
@@ -93,11 +97,22 @@ /** @private */ | ||
// --------------------------------------------- | ||
// DELETE initiated by creator, or schema deleted | ||
// state has been deleted by its creator or the schema has been deleted | ||
// --------------------------------------------- | ||
this._client.transport.addListener(`${DELETE_NOTIFICATION}-${this.id}-${this.remoteId}`, () => { | ||
this._client.transport.addListener(`${DELETE_NOTIFICATION}-${this.id}-${this.remoteId}`, async () => { | ||
this._manager._statesById.delete(this.id); | ||
this._clearTransport(); | ||
this._onDetachCallbacks.forEach(callback => callback()); | ||
this._onDeleteCallbacks.forEach(callback => callback()); | ||
for (let callback of this._onDetachCallbacks) { | ||
try { | ||
await callback(); | ||
} catch(err) { | ||
console.error(err.message); | ||
} | ||
} | ||
if (this._isOwner) { | ||
for (let callback of this._onDeleteCallbacks) { | ||
await callback(); | ||
} | ||
} | ||
this._clearDetach(); | ||
@@ -109,11 +124,16 @@ }); | ||
// --------------------------------------------- | ||
// DELETE (can only delete if creator) | ||
// the creator has called `.delete()` | ||
// --------------------------------------------- | ||
this._client.transport.addListener(`${DELETE_RESPONSE}-${this.id}-${this.remoteId}`, (reqId) => { | ||
this._client.transport.addListener(`${DELETE_RESPONSE}-${this.id}-${this.remoteId}`, async (reqId) => { | ||
this._manager._statesById.delete(this.id); | ||
this._clearTransport(); | ||
this._onDetachCallbacks.forEach(callback => callback()); | ||
this._onDeleteCallbacks.forEach(callback => callback()); | ||
for (let callback of this._onDetachCallbacks) { | ||
await callback(); | ||
} | ||
for (let callback of this._onDeleteCallbacks) { | ||
await callback(); | ||
} | ||
this._clearDetach(); | ||
@@ -129,9 +149,11 @@ resolveRequest(reqId, this); | ||
// --------------------------------------------- | ||
// DETACH | ||
// the attached node has called `.detach()` | ||
// --------------------------------------------- | ||
this._client.transport.addListener(`${DETACH_RESPONSE}-${this.id}-${this.remoteId}`, (reqId) => { | ||
this._client.transport.addListener(`${DETACH_RESPONSE}-${this.id}-${this.remoteId}`, async (reqId) => { | ||
this._manager._statesById.delete(this.id); | ||
this._clearTransport(); | ||
this._onDetachCallbacks.forEach(func => func()); | ||
for (let callback of this._onDetachCallbacks) { | ||
await callback(); | ||
} | ||
@@ -149,2 +171,39 @@ this._clearDetach(); | ||
/** | ||
* Id of the state | ||
* @type {Number} | ||
* @readonly | ||
*/ | ||
get id() { | ||
return this._id; | ||
} | ||
/** | ||
* Unique id of the state for the current node | ||
* @readonly | ||
* @type {Number} | ||
* @private | ||
*/ | ||
get remoteId() { | ||
return this._remoteId; | ||
} | ||
/** | ||
* Name of the schema | ||
* @type {String} | ||
* @readonly | ||
*/ | ||
get schemaName() { | ||
return this._schemaName; | ||
} | ||
/** | ||
* Indicates if the node is the owner of the state | ||
* @type {Boolean} | ||
* @readonly | ||
*/ | ||
get isOwner() { | ||
return this._isOwner; | ||
} | ||
/** @private */ | ||
@@ -154,8 +213,3 @@ _clearDetach() { | ||
this._onDeleteCallbacks.clear(); | ||
// Monkey patch detach so it throws if called twice. Doing nothing blocks | ||
// the process on a second `detach` call as the Promise never resolves | ||
this.detach = () => { | ||
throw new Error(`[SharedState] State "${this.schemaName} (${this.id})" already detached, cannot detach twice`); | ||
}; | ||
this._detached = true; | ||
} | ||
@@ -421,3 +475,3 @@ | ||
* Detach from the state. If the client is the creator of the state, the state | ||
* is deleted and all attached nodes get notified | ||
* is deleted and all attached nodes get notified. | ||
* | ||
@@ -430,2 +484,6 @@ * @example | ||
async detach() { | ||
if (this._detached) { | ||
throw new Error(`[SharedState] State "${this.schemaName} (${this.id})" already detached, cannot detach twice`); | ||
} | ||
this._onUpdateCallbacks.clear(); | ||
@@ -448,6 +506,8 @@ | ||
* Delete the state. Only the creator/owner of the state can use this method. | ||
* All nodes attached to the state will be deteched, triggering the `onDetach` | ||
* callback. The creator of the state will also have its `onDelete` callback | ||
* triggered. | ||
* | ||
* All nodes attached to the state will be detached, triggering any registered | ||
* `onDetach` callbacks. The creator of the state will also have its own `onDelete` | ||
* callback triggered. The local `onDeatch` and `onDelete` callbacks will be | ||
* executed *before* the returned Promise resolves | ||
* | ||
* @throws Throws if the method is called by a node which is not the owner of | ||
@@ -462,2 +522,6 @@ * the state. | ||
if (this._isOwner) { | ||
if (this._detached) { | ||
throw new Error(`[SharedState] State "${this.schemaName} (${this.id})" already deleted, cannot delete twice`); | ||
} | ||
return this.detach(); | ||
@@ -505,3 +569,4 @@ } else { | ||
/** | ||
* Register a function to execute when detaching from the state | ||
* Register a function to execute when detaching from the state. The function | ||
* will be executed before the `detach` promise resolves. | ||
* | ||
@@ -519,3 +584,4 @@ * @param {Function} callback - Callback to execute when detaching from the state. | ||
* Register a function to execute when the state is deleted. Only called if the | ||
* node was the creator of the state. Is called after `onDetach` | ||
* node was the creator of the state. Is called after `onDetach` and executed | ||
* before the `delete` Promise resolves. | ||
* | ||
@@ -522,0 +588,0 @@ * @param {Function} callback - Callback to execute when the state is deleted. |
@@ -182,4 +182,7 @@ import { isString, isFunction } from '@ircam/sc-utils'; | ||
* | ||
* Note that the states that are created by the same node are not propagated through | ||
* Notes: | ||
* - The states that are created by the same node are not propagated through | ||
* the observe callback. | ||
* - The order of execution is not guaranted, i.e. an state attached in the | ||
* `observe` callback could be created before the `async create` method resolves. | ||
* | ||
@@ -186,0 +189,0 @@ * @param {String} [schemaName] - optionnal schema name to filter the observed |
@@ -28,2 +28,3 @@ import fs from 'node:fs'; | ||
import { | ||
SERVER_ID, | ||
CLIENT_HANDSHAKE_REQUEST, | ||
@@ -336,2 +337,11 @@ CLIENT_HANDSHAKE_RESPONSE, | ||
/** | ||
* Id of the server, a constant set to -1 | ||
* @type {Number} | ||
* @readonly | ||
*/ | ||
get id() { | ||
return SERVER_ID; | ||
} | ||
/** | ||
* The `init` method is part of the initialization lifecycle of the `soundworks` | ||
@@ -338,0 +348,0 @@ * server. Most of the time, the `init` method will be implicitly called by the |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9191
351883
72
Updated@ircam/sc-gettime@^1.0.1
Updated@ircam/sc-utils@^1.1.1
Updatedchalk@^5.3.0
Updatedcross-fetch@^3.1.8
Updatedpem@^1.14.8