@volter/world-core 3.0.160 → 3.0.161

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.
@@ -1662,7 +1662,16 @@
1662
1662
  "LIVEKIT_API_SECRET": "twin-livekit-secret-for-the-worlds-own-server"
1663
1663
  },
1664
1664
  "note": "Credentials and URL are the same ones the World starts its LiveKit server with."
1665
- }
1665
+ },
1666
+ "sidePorts": [
1667
+ {
1668
+ "name": "rtc-tcp",
1669
+ "option": "rtcTcpPort",
1670
+ "flag": "--rtc-tcp-port",
1671
+ "scheme": "tcp",
1672
+ "note": "ICE/TCP media advertised on loopback at this port; the vendor binds all interfaces. Forward beside signaling for a browser on another machine."
1673
+ }
1674
+ ]
1666
1675
  },
1667
1676
  "merge": {
1668
1677
  "adoption": {
@@ -3045,6 +3054,102 @@
3045
3054
  },
3046
3055
  "serveExport": "createTurbopufferTwinServer"
3047
3056
  },
3057
+ "twitch": {
3058
+ "adoption": {
3059
+ "sdks": [],
3060
+ "envStems": [
3061
+ "TWITCH"
3062
+ ]
3063
+ },
3064
+ "hosts": [
3065
+ {
3066
+ "host": "api.twitch.tv",
3067
+ "pathPattern": "^/helix/|^/_twin/"
3068
+ },
3069
+ {
3070
+ "host": "id.twitch.tv",
3071
+ "pathPattern": "^/oauth2/|^/_twin/"
3072
+ },
3073
+ {
3074
+ "host": "www.twitch.tv",
3075
+ "pathPattern": "^/$|^/login/?$|^/popout/[A-Za-z0-9_]{1,25}/chat/?$|^/[A-Za-z0-9_]{1,25}/?$|^/_twin/"
3076
+ },
3077
+ {
3078
+ "host": "twitch.tv",
3079
+ "pathPattern": "^/$|^/login/?$|^/popout/[A-Za-z0-9_]{1,25}/chat/?$|^/[A-Za-z0-9_]{1,25}/?$|^/_twin/"
3080
+ },
3081
+ {
3082
+ "host": "m.twitch.tv",
3083
+ "pathPattern": "^/$|^/login/?$|^/popout/[A-Za-z0-9_]{1,25}/chat/?$|^/[A-Za-z0-9_]{1,25}/?$|^/_twin/"
3084
+ },
3085
+ {
3086
+ "host": "dashboard.twitch.tv",
3087
+ "pathPattern": "^/u/[A-Za-z0-9_]{1,25}/(?:stream-manager|settings/stream)/?$"
3088
+ },
3089
+ {
3090
+ "host": "player.twitch.tv",
3091
+ "pathPattern": "^/$"
3092
+ },
3093
+ {
3094
+ "host": "irc-ws.chat.twitch.tv"
3095
+ },
3096
+ {
3097
+ "host": "usher.ttvnw.net",
3098
+ "pathPattern": "^/api/channel/hls/"
3099
+ }
3100
+ ],
3101
+ "archetype": "crud",
3102
+ "protocol": {
3103
+ "declared": "3",
3104
+ "major": 3,
3105
+ "standing": "current"
3106
+ },
3107
+ "transport": "rest",
3108
+ "resources": [
3109
+ "user",
3110
+ "channel",
3111
+ "stream",
3112
+ "chat_message",
3113
+ "application",
3114
+ "_token",
3115
+ "_authorization_code",
3116
+ "_client_secret",
3117
+ "_stream_key",
3118
+ "_live",
3119
+ "_live_segment"
3120
+ ],
3121
+ "endpointEnvNone": "Twitch's clients address api.twitch.tv, id.twitch.tv and irc-ws.chat.twitch.tv by their published URLs; no SDK reads a base-URL variable",
3122
+ "credentialDoor": {
3123
+ "path": "/_twin/console",
3124
+ "body": {
3125
+ "login": "worldchannel",
3126
+ "password": "world-password",
3127
+ "email": "worldchannel@example.com",
3128
+ "application": {
3129
+ "name": "World App",
3130
+ "redirect_uris": [
3131
+ "http://localhost:3000"
3132
+ ]
3133
+ }
3134
+ },
3135
+ "fill": {
3136
+ "TWITCH_CLIENT_ID": "client_id",
3137
+ "TWITCH_CLIENT_SECRET": "client_secret",
3138
+ "TWITCH_CHANNEL": "login"
3139
+ }
3140
+ },
3141
+ "sidePorts": [
3142
+ {
3143
+ "name": "ingest",
3144
+ "option": "ingestPort",
3145
+ "flag": "--ingest-port",
3146
+ "scheme": "rtmp",
3147
+ "path": "/app",
3148
+ "note": "Twitch's RTMP ingest (rtmp://<ingest-server>/app/<stream-key>): OBS publishes the channel's broadcast here"
3149
+ }
3150
+ ],
3151
+ "serveExport": "createTwitchTwinServer"
3152
+ },
3048
3153
  "upstash": {
3049
3154
  "adoption": {
3050
3155
  "sdks": [
@@ -198,6 +198,9 @@ export function rtmpSession(sink, publisher, log = () => { }) {
198
198
  catch (error) {
199
199
  if (!(error instanceof RtmpRefusal))
200
200
  throw error;
201
+ // said in the World's log too, not only to the publisher: an ended broadcast is otherwise unreadable afterwards
202
+ // (the stream key is the publish name, so it is never logged)
203
+ log(`a publish to ${app || 'its app'} was refused and ended: ${error.message}`);
201
204
  status(publishStream, 'error', error.code, error.message);
202
205
  await stop();
203
206
  close();
@@ -1662,7 +1662,16 @@
1662
1662
  "LIVEKIT_API_SECRET": "twin-livekit-secret-for-the-worlds-own-server"
1663
1663
  },
1664
1664
  "note": "Credentials and URL are the same ones the World starts its LiveKit server with."
1665
- }
1665
+ },
1666
+ "sidePorts": [
1667
+ {
1668
+ "name": "rtc-tcp",
1669
+ "option": "rtcTcpPort",
1670
+ "flag": "--rtc-tcp-port",
1671
+ "scheme": "tcp",
1672
+ "note": "ICE/TCP media advertised on loopback at this port; the vendor binds all interfaces. Forward beside signaling for a browser on another machine."
1673
+ }
1674
+ ]
1666
1675
  },
1667
1676
  "merge": {
1668
1677
  "adoption": {
@@ -3045,6 +3054,102 @@
3045
3054
  },
3046
3055
  "serveExport": "createTurbopufferTwinServer"
3047
3056
  },
3057
+ "twitch": {
3058
+ "adoption": {
3059
+ "sdks": [],
3060
+ "envStems": [
3061
+ "TWITCH"
3062
+ ]
3063
+ },
3064
+ "hosts": [
3065
+ {
3066
+ "host": "api.twitch.tv",
3067
+ "pathPattern": "^/helix/|^/_twin/"
3068
+ },
3069
+ {
3070
+ "host": "id.twitch.tv",
3071
+ "pathPattern": "^/oauth2/|^/_twin/"
3072
+ },
3073
+ {
3074
+ "host": "www.twitch.tv",
3075
+ "pathPattern": "^/$|^/login/?$|^/popout/[A-Za-z0-9_]{1,25}/chat/?$|^/[A-Za-z0-9_]{1,25}/?$|^/_twin/"
3076
+ },
3077
+ {
3078
+ "host": "twitch.tv",
3079
+ "pathPattern": "^/$|^/login/?$|^/popout/[A-Za-z0-9_]{1,25}/chat/?$|^/[A-Za-z0-9_]{1,25}/?$|^/_twin/"
3080
+ },
3081
+ {
3082
+ "host": "m.twitch.tv",
3083
+ "pathPattern": "^/$|^/login/?$|^/popout/[A-Za-z0-9_]{1,25}/chat/?$|^/[A-Za-z0-9_]{1,25}/?$|^/_twin/"
3084
+ },
3085
+ {
3086
+ "host": "dashboard.twitch.tv",
3087
+ "pathPattern": "^/u/[A-Za-z0-9_]{1,25}/(?:stream-manager|settings/stream)/?$"
3088
+ },
3089
+ {
3090
+ "host": "player.twitch.tv",
3091
+ "pathPattern": "^/$"
3092
+ },
3093
+ {
3094
+ "host": "irc-ws.chat.twitch.tv"
3095
+ },
3096
+ {
3097
+ "host": "usher.ttvnw.net",
3098
+ "pathPattern": "^/api/channel/hls/"
3099
+ }
3100
+ ],
3101
+ "archetype": "crud",
3102
+ "protocol": {
3103
+ "declared": "3",
3104
+ "major": 3,
3105
+ "standing": "current"
3106
+ },
3107
+ "transport": "rest",
3108
+ "resources": [
3109
+ "user",
3110
+ "channel",
3111
+ "stream",
3112
+ "chat_message",
3113
+ "application",
3114
+ "_token",
3115
+ "_authorization_code",
3116
+ "_client_secret",
3117
+ "_stream_key",
3118
+ "_live",
3119
+ "_live_segment"
3120
+ ],
3121
+ "endpointEnvNone": "Twitch's clients address api.twitch.tv, id.twitch.tv and irc-ws.chat.twitch.tv by their published URLs; no SDK reads a base-URL variable",
3122
+ "credentialDoor": {
3123
+ "path": "/_twin/console",
3124
+ "body": {
3125
+ "login": "worldchannel",
3126
+ "password": "world-password",
3127
+ "email": "worldchannel@example.com",
3128
+ "application": {
3129
+ "name": "World App",
3130
+ "redirect_uris": [
3131
+ "http://localhost:3000"
3132
+ ]
3133
+ }
3134
+ },
3135
+ "fill": {
3136
+ "TWITCH_CLIENT_ID": "client_id",
3137
+ "TWITCH_CLIENT_SECRET": "client_secret",
3138
+ "TWITCH_CHANNEL": "login"
3139
+ }
3140
+ },
3141
+ "sidePorts": [
3142
+ {
3143
+ "name": "ingest",
3144
+ "option": "ingestPort",
3145
+ "flag": "--ingest-port",
3146
+ "scheme": "rtmp",
3147
+ "path": "/app",
3148
+ "note": "Twitch's RTMP ingest (rtmp://<ingest-server>/app/<stream-key>): OBS publishes the channel's broadcast here"
3149
+ }
3150
+ ],
3151
+ "serveExport": "createTwitchTwinServer"
3152
+ },
3048
3153
  "upstash": {
3049
3154
  "adoption": {
3050
3155
  "sdks": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/world-core",
3
- "version": "3.0.160",
3
+ "version": "3.0.161",
4
4
  "description": "The kernel of Volter World: one log per twin, branches as pointers, checkpoints, the fold that keeps a twin current, the head that performs a write against the vendor, references, and the git plane. A twin package builds on it; the runtime serves it.",
5
5
  "keywords": [
6
6
  "twin",
@@ -182,5 +182,13 @@
182
182
  },
183
183
  "optionalDependencies": {
184
184
  "@xmldom/xmldom": "0.9.12"
185
+ },
186
+ "packageManager": "pnpm@12.15.0",
187
+ "devEngines": {
188
+ "packageManager": {
189
+ "name": "pnpm",
190
+ "version": "12.15.0",
191
+ "onFail": "error"
192
+ }
185
193
  }
186
194
  }
package/src/live/rtmp.ts CHANGED
@@ -204,6 +204,9 @@ export function rtmpSession(sink: TwinStreamSink, publisher: RtmpPublisher, log:
204
204
  const media = async (hand: () => void | Promise<void>): Promise<void> => {
205
205
  try { await hand(); } catch (error) {
206
206
  if (!(error instanceof RtmpRefusal)) throw error;
207
+ // said in the World's log too, not only to the publisher: an ended broadcast is otherwise unreadable afterwards
208
+ // (the stream key is the publish name, so it is never logged)
209
+ log(`a publish to ${app || 'its app'} was refused and ended: ${error.message}`);
207
210
  status(publishStream, 'error', error.code, error.message);
208
211
  await stop();
209
212
  close();