@thestatic-tv/dcl-sdk 1.0.1 → 1.0.3
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/dist/index.d.mts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +79 -14
- package/dist/index.mjs +79 -14
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -84,6 +84,26 @@ interface InteractionResponse {
|
|
|
84
84
|
alreadyExists: boolean;
|
|
85
85
|
version: string;
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Scene stats for display in-world
|
|
89
|
+
*/
|
|
90
|
+
interface SceneStats {
|
|
91
|
+
date: string;
|
|
92
|
+
totalSessions: number;
|
|
93
|
+
uniqueVisitors: number;
|
|
94
|
+
totalMinutes: number;
|
|
95
|
+
visitorNumber: number | null;
|
|
96
|
+
isFirstVisitor: boolean;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Scene stats response from the API
|
|
100
|
+
*/
|
|
101
|
+
interface SceneStatsResponse {
|
|
102
|
+
success: boolean;
|
|
103
|
+
stats: SceneStats;
|
|
104
|
+
sceneName: string | null;
|
|
105
|
+
version: string;
|
|
106
|
+
}
|
|
87
107
|
|
|
88
108
|
/**
|
|
89
109
|
* Guide module - fetch channel lineup from thestatic.tv
|
|
@@ -128,7 +148,7 @@ declare class GuideModule {
|
|
|
128
148
|
declare class SessionModule {
|
|
129
149
|
private client;
|
|
130
150
|
private sessionId;
|
|
131
|
-
private
|
|
151
|
+
private heartbeatTimerId;
|
|
132
152
|
private isActive;
|
|
133
153
|
constructor(client: StaticTVClient);
|
|
134
154
|
/**
|
|
@@ -141,7 +161,7 @@ declare class SessionModule {
|
|
|
141
161
|
*/
|
|
142
162
|
startSession(metadata?: Record<string, unknown>): Promise<string | null>;
|
|
143
163
|
/**
|
|
144
|
-
* Start the heartbeat interval
|
|
164
|
+
* Start the heartbeat interval using DCL-compatible timer
|
|
145
165
|
*/
|
|
146
166
|
private startHeartbeat;
|
|
147
167
|
/**
|
|
@@ -160,6 +180,11 @@ declare class SessionModule {
|
|
|
160
180
|
* Check if a session is currently active
|
|
161
181
|
*/
|
|
162
182
|
isSessionActive(): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Get scene stats (visitors, sessions, etc.)
|
|
185
|
+
* Useful for displaying metrics in-world
|
|
186
|
+
*/
|
|
187
|
+
getStats(): Promise<SceneStatsResponse['stats'] | null>;
|
|
163
188
|
}
|
|
164
189
|
|
|
165
190
|
/**
|
|
@@ -168,7 +193,7 @@ declare class SessionModule {
|
|
|
168
193
|
|
|
169
194
|
declare class HeartbeatModule {
|
|
170
195
|
private client;
|
|
171
|
-
private
|
|
196
|
+
private watchTimerId;
|
|
172
197
|
private currentChannel;
|
|
173
198
|
private isWatching;
|
|
174
199
|
constructor(client: StaticTVClient);
|
|
@@ -294,4 +319,4 @@ declare class StaticTVClient {
|
|
|
294
319
|
destroy(): Promise<void>;
|
|
295
320
|
}
|
|
296
321
|
|
|
297
|
-
export { type Channel, GuideModule, type GuideResponse, HeartbeatModule, type HeartbeatResponse, type InteractionResponse, InteractionsModule, KEY_TYPE_CHANNEL, KEY_TYPE_SCENE, SessionModule, type SessionResponse, StaticTVClient, type StaticTVConfig, type Vod };
|
|
322
|
+
export { type Channel, GuideModule, type GuideResponse, HeartbeatModule, type HeartbeatResponse, type InteractionResponse, InteractionsModule, KEY_TYPE_CHANNEL, KEY_TYPE_SCENE, type SceneStats, type SceneStatsResponse, SessionModule, type SessionResponse, StaticTVClient, type StaticTVConfig, type Vod };
|
package/dist/index.d.ts
CHANGED
|
@@ -84,6 +84,26 @@ interface InteractionResponse {
|
|
|
84
84
|
alreadyExists: boolean;
|
|
85
85
|
version: string;
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Scene stats for display in-world
|
|
89
|
+
*/
|
|
90
|
+
interface SceneStats {
|
|
91
|
+
date: string;
|
|
92
|
+
totalSessions: number;
|
|
93
|
+
uniqueVisitors: number;
|
|
94
|
+
totalMinutes: number;
|
|
95
|
+
visitorNumber: number | null;
|
|
96
|
+
isFirstVisitor: boolean;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Scene stats response from the API
|
|
100
|
+
*/
|
|
101
|
+
interface SceneStatsResponse {
|
|
102
|
+
success: boolean;
|
|
103
|
+
stats: SceneStats;
|
|
104
|
+
sceneName: string | null;
|
|
105
|
+
version: string;
|
|
106
|
+
}
|
|
87
107
|
|
|
88
108
|
/**
|
|
89
109
|
* Guide module - fetch channel lineup from thestatic.tv
|
|
@@ -128,7 +148,7 @@ declare class GuideModule {
|
|
|
128
148
|
declare class SessionModule {
|
|
129
149
|
private client;
|
|
130
150
|
private sessionId;
|
|
131
|
-
private
|
|
151
|
+
private heartbeatTimerId;
|
|
132
152
|
private isActive;
|
|
133
153
|
constructor(client: StaticTVClient);
|
|
134
154
|
/**
|
|
@@ -141,7 +161,7 @@ declare class SessionModule {
|
|
|
141
161
|
*/
|
|
142
162
|
startSession(metadata?: Record<string, unknown>): Promise<string | null>;
|
|
143
163
|
/**
|
|
144
|
-
* Start the heartbeat interval
|
|
164
|
+
* Start the heartbeat interval using DCL-compatible timer
|
|
145
165
|
*/
|
|
146
166
|
private startHeartbeat;
|
|
147
167
|
/**
|
|
@@ -160,6 +180,11 @@ declare class SessionModule {
|
|
|
160
180
|
* Check if a session is currently active
|
|
161
181
|
*/
|
|
162
182
|
isSessionActive(): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Get scene stats (visitors, sessions, etc.)
|
|
185
|
+
* Useful for displaying metrics in-world
|
|
186
|
+
*/
|
|
187
|
+
getStats(): Promise<SceneStatsResponse['stats'] | null>;
|
|
163
188
|
}
|
|
164
189
|
|
|
165
190
|
/**
|
|
@@ -168,7 +193,7 @@ declare class SessionModule {
|
|
|
168
193
|
|
|
169
194
|
declare class HeartbeatModule {
|
|
170
195
|
private client;
|
|
171
|
-
private
|
|
196
|
+
private watchTimerId;
|
|
172
197
|
private currentChannel;
|
|
173
198
|
private isWatching;
|
|
174
199
|
constructor(client: StaticTVClient);
|
|
@@ -294,4 +319,4 @@ declare class StaticTVClient {
|
|
|
294
319
|
destroy(): Promise<void>;
|
|
295
320
|
}
|
|
296
321
|
|
|
297
|
-
export { type Channel, GuideModule, type GuideResponse, HeartbeatModule, type HeartbeatResponse, type InteractionResponse, InteractionsModule, KEY_TYPE_CHANNEL, KEY_TYPE_SCENE, SessionModule, type SessionResponse, StaticTVClient, type StaticTVConfig, type Vod };
|
|
322
|
+
export { type Channel, GuideModule, type GuideResponse, HeartbeatModule, type HeartbeatResponse, type InteractionResponse, InteractionsModule, KEY_TYPE_CHANNEL, KEY_TYPE_SCENE, type SceneStats, type SceneStatsResponse, SessionModule, type SessionResponse, StaticTVClient, type StaticTVConfig, type Vod };
|
package/dist/index.js
CHANGED
|
@@ -99,7 +99,7 @@ var GuideModule = class {
|
|
|
99
99
|
// src/utils/identity.ts
|
|
100
100
|
function getPlayerWallet() {
|
|
101
101
|
try {
|
|
102
|
-
const { getPlayer } = require("@dcl/sdk/
|
|
102
|
+
const { getPlayer } = require("@dcl/sdk/players");
|
|
103
103
|
const player = getPlayer();
|
|
104
104
|
return player?.userId ?? null;
|
|
105
105
|
} catch {
|
|
@@ -108,7 +108,7 @@ function getPlayerWallet() {
|
|
|
108
108
|
}
|
|
109
109
|
function getPlayerDisplayName() {
|
|
110
110
|
try {
|
|
111
|
-
const { getPlayer } = require("@dcl/sdk/
|
|
111
|
+
const { getPlayer } = require("@dcl/sdk/players");
|
|
112
112
|
const player = getPlayer();
|
|
113
113
|
return player?.name ?? null;
|
|
114
114
|
} catch {
|
|
@@ -116,11 +116,54 @@ function getPlayerDisplayName() {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// src/utils/timer.ts
|
|
120
|
+
var import_ecs = require("@dcl/sdk/ecs");
|
|
121
|
+
var nextTimerId = 1;
|
|
122
|
+
var timers = /* @__PURE__ */ new Map();
|
|
123
|
+
var systemAdded = false;
|
|
124
|
+
function ensureTimerSystem() {
|
|
125
|
+
if (systemAdded) return;
|
|
126
|
+
import_ecs.engine.addSystem((dt) => {
|
|
127
|
+
for (const timer of timers.values()) {
|
|
128
|
+
if (!timer.active) continue;
|
|
129
|
+
timer.elapsedTime += dt;
|
|
130
|
+
if (timer.elapsedTime >= timer.intervalSeconds) {
|
|
131
|
+
timer.elapsedTime = 0;
|
|
132
|
+
try {
|
|
133
|
+
timer.callback();
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.error("[StaticTV Timer] Callback error:", e);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
systemAdded = true;
|
|
141
|
+
}
|
|
142
|
+
function dclSetInterval(callback, intervalMs) {
|
|
143
|
+
ensureTimerSystem();
|
|
144
|
+
const id = nextTimerId++;
|
|
145
|
+
timers.set(id, {
|
|
146
|
+
id,
|
|
147
|
+
callback,
|
|
148
|
+
intervalSeconds: intervalMs / 1e3,
|
|
149
|
+
elapsedTime: 0,
|
|
150
|
+
active: true
|
|
151
|
+
});
|
|
152
|
+
return id;
|
|
153
|
+
}
|
|
154
|
+
function dclClearInterval(timerId) {
|
|
155
|
+
const timer = timers.get(timerId);
|
|
156
|
+
if (timer) {
|
|
157
|
+
timer.active = false;
|
|
158
|
+
timers.delete(timerId);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
119
162
|
// src/modules/session.ts
|
|
120
163
|
var SessionModule = class {
|
|
121
164
|
constructor(client) {
|
|
122
165
|
this.sessionId = null;
|
|
123
|
-
this.
|
|
166
|
+
this.heartbeatTimerId = null;
|
|
124
167
|
this.isActive = false;
|
|
125
168
|
this.client = client;
|
|
126
169
|
}
|
|
@@ -163,12 +206,12 @@ var SessionModule = class {
|
|
|
163
206
|
}
|
|
164
207
|
}
|
|
165
208
|
/**
|
|
166
|
-
* Start the heartbeat interval
|
|
209
|
+
* Start the heartbeat interval using DCL-compatible timer
|
|
167
210
|
*/
|
|
168
211
|
startHeartbeat() {
|
|
169
|
-
if (this.
|
|
212
|
+
if (this.heartbeatTimerId !== null) return;
|
|
170
213
|
const interval = this.client.getConfig().sessionHeartbeatInterval || 3e4;
|
|
171
|
-
this.
|
|
214
|
+
this.heartbeatTimerId = dclSetInterval(() => {
|
|
172
215
|
this.sendHeartbeat();
|
|
173
216
|
}, interval);
|
|
174
217
|
}
|
|
@@ -195,9 +238,9 @@ var SessionModule = class {
|
|
|
195
238
|
*/
|
|
196
239
|
async endSession() {
|
|
197
240
|
if (!this.isActive) return;
|
|
198
|
-
if (this.
|
|
199
|
-
|
|
200
|
-
this.
|
|
241
|
+
if (this.heartbeatTimerId !== null) {
|
|
242
|
+
dclClearInterval(this.heartbeatTimerId);
|
|
243
|
+
this.heartbeatTimerId = null;
|
|
201
244
|
}
|
|
202
245
|
if (this.sessionId) {
|
|
203
246
|
try {
|
|
@@ -228,12 +271,34 @@ var SessionModule = class {
|
|
|
228
271
|
isSessionActive() {
|
|
229
272
|
return this.isActive;
|
|
230
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Get scene stats (visitors, sessions, etc.)
|
|
276
|
+
* Useful for displaying metrics in-world
|
|
277
|
+
*/
|
|
278
|
+
async getStats() {
|
|
279
|
+
try {
|
|
280
|
+
const wallet = getPlayerWallet();
|
|
281
|
+
const queryParam = wallet ? `?wallet=${wallet}` : "";
|
|
282
|
+
const response = await this.client.request(
|
|
283
|
+
`/scene-stats${queryParam}`,
|
|
284
|
+
{ method: "GET" }
|
|
285
|
+
);
|
|
286
|
+
if (response.success && response.stats) {
|
|
287
|
+
this.client.log("Stats fetched:", response.stats);
|
|
288
|
+
return response.stats;
|
|
289
|
+
}
|
|
290
|
+
return null;
|
|
291
|
+
} catch (error) {
|
|
292
|
+
this.client.log(`Failed to fetch stats: ${error}`);
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
231
296
|
};
|
|
232
297
|
|
|
233
298
|
// src/modules/heartbeat.ts
|
|
234
299
|
var HeartbeatModule = class {
|
|
235
300
|
constructor(client) {
|
|
236
|
-
this.
|
|
301
|
+
this.watchTimerId = null;
|
|
237
302
|
this.currentChannel = null;
|
|
238
303
|
this.isWatching = false;
|
|
239
304
|
this.client = client;
|
|
@@ -256,7 +321,7 @@ var HeartbeatModule = class {
|
|
|
256
321
|
this.isWatching = true;
|
|
257
322
|
this.sendHeartbeat();
|
|
258
323
|
const interval = this.client.getConfig().watchHeartbeatInterval || 6e4;
|
|
259
|
-
this.
|
|
324
|
+
this.watchTimerId = dclSetInterval(() => {
|
|
260
325
|
this.sendHeartbeat();
|
|
261
326
|
}, interval);
|
|
262
327
|
this.client.log(`Started watching ${channelSlug}`);
|
|
@@ -266,9 +331,9 @@ var HeartbeatModule = class {
|
|
|
266
331
|
*/
|
|
267
332
|
stopWatching() {
|
|
268
333
|
if (!this.isWatching) return;
|
|
269
|
-
if (this.
|
|
270
|
-
|
|
271
|
-
this.
|
|
334
|
+
if (this.watchTimerId !== null) {
|
|
335
|
+
dclClearInterval(this.watchTimerId);
|
|
336
|
+
this.watchTimerId = null;
|
|
272
337
|
}
|
|
273
338
|
this.client.log(`Stopped watching ${this.currentChannel}`);
|
|
274
339
|
this.currentChannel = null;
|
package/dist/index.mjs
CHANGED
|
@@ -74,7 +74,7 @@ var GuideModule = class {
|
|
|
74
74
|
// src/utils/identity.ts
|
|
75
75
|
function getPlayerWallet() {
|
|
76
76
|
try {
|
|
77
|
-
const { getPlayer } = __require("@dcl/sdk/
|
|
77
|
+
const { getPlayer } = __require("@dcl/sdk/players");
|
|
78
78
|
const player = getPlayer();
|
|
79
79
|
return player?.userId ?? null;
|
|
80
80
|
} catch {
|
|
@@ -83,7 +83,7 @@ function getPlayerWallet() {
|
|
|
83
83
|
}
|
|
84
84
|
function getPlayerDisplayName() {
|
|
85
85
|
try {
|
|
86
|
-
const { getPlayer } = __require("@dcl/sdk/
|
|
86
|
+
const { getPlayer } = __require("@dcl/sdk/players");
|
|
87
87
|
const player = getPlayer();
|
|
88
88
|
return player?.name ?? null;
|
|
89
89
|
} catch {
|
|
@@ -91,11 +91,54 @@ function getPlayerDisplayName() {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
// src/utils/timer.ts
|
|
95
|
+
import { engine } from "@dcl/sdk/ecs";
|
|
96
|
+
var nextTimerId = 1;
|
|
97
|
+
var timers = /* @__PURE__ */ new Map();
|
|
98
|
+
var systemAdded = false;
|
|
99
|
+
function ensureTimerSystem() {
|
|
100
|
+
if (systemAdded) return;
|
|
101
|
+
engine.addSystem((dt) => {
|
|
102
|
+
for (const timer of timers.values()) {
|
|
103
|
+
if (!timer.active) continue;
|
|
104
|
+
timer.elapsedTime += dt;
|
|
105
|
+
if (timer.elapsedTime >= timer.intervalSeconds) {
|
|
106
|
+
timer.elapsedTime = 0;
|
|
107
|
+
try {
|
|
108
|
+
timer.callback();
|
|
109
|
+
} catch (e) {
|
|
110
|
+
console.error("[StaticTV Timer] Callback error:", e);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
systemAdded = true;
|
|
116
|
+
}
|
|
117
|
+
function dclSetInterval(callback, intervalMs) {
|
|
118
|
+
ensureTimerSystem();
|
|
119
|
+
const id = nextTimerId++;
|
|
120
|
+
timers.set(id, {
|
|
121
|
+
id,
|
|
122
|
+
callback,
|
|
123
|
+
intervalSeconds: intervalMs / 1e3,
|
|
124
|
+
elapsedTime: 0,
|
|
125
|
+
active: true
|
|
126
|
+
});
|
|
127
|
+
return id;
|
|
128
|
+
}
|
|
129
|
+
function dclClearInterval(timerId) {
|
|
130
|
+
const timer = timers.get(timerId);
|
|
131
|
+
if (timer) {
|
|
132
|
+
timer.active = false;
|
|
133
|
+
timers.delete(timerId);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
94
137
|
// src/modules/session.ts
|
|
95
138
|
var SessionModule = class {
|
|
96
139
|
constructor(client) {
|
|
97
140
|
this.sessionId = null;
|
|
98
|
-
this.
|
|
141
|
+
this.heartbeatTimerId = null;
|
|
99
142
|
this.isActive = false;
|
|
100
143
|
this.client = client;
|
|
101
144
|
}
|
|
@@ -138,12 +181,12 @@ var SessionModule = class {
|
|
|
138
181
|
}
|
|
139
182
|
}
|
|
140
183
|
/**
|
|
141
|
-
* Start the heartbeat interval
|
|
184
|
+
* Start the heartbeat interval using DCL-compatible timer
|
|
142
185
|
*/
|
|
143
186
|
startHeartbeat() {
|
|
144
|
-
if (this.
|
|
187
|
+
if (this.heartbeatTimerId !== null) return;
|
|
145
188
|
const interval = this.client.getConfig().sessionHeartbeatInterval || 3e4;
|
|
146
|
-
this.
|
|
189
|
+
this.heartbeatTimerId = dclSetInterval(() => {
|
|
147
190
|
this.sendHeartbeat();
|
|
148
191
|
}, interval);
|
|
149
192
|
}
|
|
@@ -170,9 +213,9 @@ var SessionModule = class {
|
|
|
170
213
|
*/
|
|
171
214
|
async endSession() {
|
|
172
215
|
if (!this.isActive) return;
|
|
173
|
-
if (this.
|
|
174
|
-
|
|
175
|
-
this.
|
|
216
|
+
if (this.heartbeatTimerId !== null) {
|
|
217
|
+
dclClearInterval(this.heartbeatTimerId);
|
|
218
|
+
this.heartbeatTimerId = null;
|
|
176
219
|
}
|
|
177
220
|
if (this.sessionId) {
|
|
178
221
|
try {
|
|
@@ -203,12 +246,34 @@ var SessionModule = class {
|
|
|
203
246
|
isSessionActive() {
|
|
204
247
|
return this.isActive;
|
|
205
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Get scene stats (visitors, sessions, etc.)
|
|
251
|
+
* Useful for displaying metrics in-world
|
|
252
|
+
*/
|
|
253
|
+
async getStats() {
|
|
254
|
+
try {
|
|
255
|
+
const wallet = getPlayerWallet();
|
|
256
|
+
const queryParam = wallet ? `?wallet=${wallet}` : "";
|
|
257
|
+
const response = await this.client.request(
|
|
258
|
+
`/scene-stats${queryParam}`,
|
|
259
|
+
{ method: "GET" }
|
|
260
|
+
);
|
|
261
|
+
if (response.success && response.stats) {
|
|
262
|
+
this.client.log("Stats fetched:", response.stats);
|
|
263
|
+
return response.stats;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
} catch (error) {
|
|
267
|
+
this.client.log(`Failed to fetch stats: ${error}`);
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
206
271
|
};
|
|
207
272
|
|
|
208
273
|
// src/modules/heartbeat.ts
|
|
209
274
|
var HeartbeatModule = class {
|
|
210
275
|
constructor(client) {
|
|
211
|
-
this.
|
|
276
|
+
this.watchTimerId = null;
|
|
212
277
|
this.currentChannel = null;
|
|
213
278
|
this.isWatching = false;
|
|
214
279
|
this.client = client;
|
|
@@ -231,7 +296,7 @@ var HeartbeatModule = class {
|
|
|
231
296
|
this.isWatching = true;
|
|
232
297
|
this.sendHeartbeat();
|
|
233
298
|
const interval = this.client.getConfig().watchHeartbeatInterval || 6e4;
|
|
234
|
-
this.
|
|
299
|
+
this.watchTimerId = dclSetInterval(() => {
|
|
235
300
|
this.sendHeartbeat();
|
|
236
301
|
}, interval);
|
|
237
302
|
this.client.log(`Started watching ${channelSlug}`);
|
|
@@ -241,9 +306,9 @@ var HeartbeatModule = class {
|
|
|
241
306
|
*/
|
|
242
307
|
stopWatching() {
|
|
243
308
|
if (!this.isWatching) return;
|
|
244
|
-
if (this.
|
|
245
|
-
|
|
246
|
-
this.
|
|
309
|
+
if (this.watchTimerId !== null) {
|
|
310
|
+
dclClearInterval(this.watchTimerId);
|
|
311
|
+
this.watchTimerId = null;
|
|
247
312
|
}
|
|
248
313
|
this.client.log(`Stopped watching ${this.currentChannel}`);
|
|
249
314
|
this.currentChannel = null;
|
package/package.json
CHANGED