@cloudcare/cocos-sdk 0.1.0-alpha.5 → 0.1.0-alpha.6
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 +13 -1
- package/bin/cli.cjs +40 -21
- package/bin/legacy-asset-hashes.json +27 -0
- package/bin/managed-assets.cjs +67 -0
- package/dist/creator2/core/client.d.ts +23 -7
- package/dist/creator2/core/client.d.ts.map +1 -1
- package/dist/creator2/core/client.js +74 -28
- package/dist/creator2/core/client.js.map +1 -1
- package/dist/creator2/core/index.d.ts +1 -1
- package/dist/creator2/core/index.d.ts.map +1 -1
- package/dist/creator2/core/index.js.map +1 -1
- package/dist/creator2/core/plugin-api.d.ts +15 -0
- package/dist/creator2/core/plugin-api.d.ts.map +1 -0
- package/dist/creator2/core/plugin-api.js +3 -0
- package/dist/creator2/core/plugin-api.js.map +1 -0
- package/dist/creator2/core/types.d.ts +0 -78
- package/dist/creator2/core/types.d.ts.map +1 -1
- package/dist/creator2/core/validation.d.ts +0 -11
- package/dist/creator2/core/validation.d.ts.map +1 -1
- package/dist/creator2/core/validation.js +0 -63
- package/dist/creator2/core/validation.js.map +1 -1
- package/dist/creator2/core/version.d.ts +1 -1
- package/dist/creator2/core/version.js +1 -1
- package/dist/creator2/creator2/auto.d.ts +1 -3
- package/dist/creator2/creator2/auto.d.ts.map +1 -1
- package/dist/creator2/creator2/auto.js +0 -25
- package/dist/creator2/creator2/auto.js.map +1 -1
- package/dist/creator2/creator2/index.d.ts +0 -7
- package/dist/creator2/creator2/index.d.ts.map +1 -1
- package/dist/creator2/creator2/index.js +1 -13
- package/dist/creator2/creator2/index.js.map +1 -1
- package/dist/creator2/creator2/transport.d.ts +0 -1
- package/dist/creator2/creator2/transport.d.ts.map +1 -1
- package/dist/creator2/creator2/transport.js +0 -4
- package/dist/creator2/creator2/transport.js.map +1 -1
- package/dist/creator3/core/client.d.ts +23 -7
- package/dist/creator3/core/client.d.ts.map +1 -1
- package/dist/creator3/core/client.js +72 -28
- package/dist/creator3/core/client.js.map +1 -1
- package/dist/creator3/core/index.d.ts +1 -1
- package/dist/creator3/core/index.d.ts.map +1 -1
- package/dist/creator3/core/index.js.map +1 -1
- package/dist/creator3/core/plugin-api.d.ts +15 -0
- package/dist/creator3/core/plugin-api.d.ts.map +1 -0
- package/dist/creator3/core/plugin-api.js +2 -0
- package/dist/creator3/core/plugin-api.js.map +1 -0
- package/dist/creator3/core/types.d.ts +0 -78
- package/dist/creator3/core/types.d.ts.map +1 -1
- package/dist/creator3/core/validation.d.ts +0 -11
- package/dist/creator3/core/validation.d.ts.map +1 -1
- package/dist/creator3/core/validation.js +0 -61
- package/dist/creator3/core/validation.js.map +1 -1
- package/dist/creator3/core/version.d.ts +1 -1
- package/dist/creator3/core/version.js +1 -1
- package/dist/creator3/creator3/auto.d.ts +1 -3
- package/dist/creator3/creator3/auto.d.ts.map +1 -1
- package/dist/creator3/creator3/auto.js +1 -26
- package/dist/creator3/creator3/auto.js.map +1 -1
- package/dist/creator3/creator3/index.d.ts +0 -7
- package/dist/creator3/creator3/index.d.ts.map +1 -1
- package/dist/creator3/creator3/index.js +1 -12
- package/dist/creator3/creator3/index.js.map +1 -1
- package/dist/creator3/creator3/transport.d.ts +0 -1
- package/dist/creator3/creator3/transport.d.ts.map +1 -1
- package/dist/creator3/creator3/transport.js +0 -4
- package/dist/creator3/creator3/transport.js.map +1 -1
- package/extensions/creator2/install-native.cjs +52 -30
- package/extensions/creator2/install-spm.cjs +16 -8
- package/extensions/creator2/legacy-asset-hashes.json +27 -0
- package/extensions/creator2/managed-assets.cjs +67 -0
- package/extensions/creator3/install-native.cjs +52 -30
- package/extensions/creator3/install-spm.cjs +16 -8
- package/extensions/creator3/legacy-asset-hashes.json +27 -0
- package/extensions/creator3/managed-assets.cjs +67 -0
- package/native/android/src/main/java/com/ft/sdk/cocos/FTBridgeTransport.java +85 -0
- package/native/android/src/main/java/com/ft/sdk/cocos/FTCocosBridge.java +2 -192
- package/native/android/src/main/java/com/ft/sdk/cocos/FTCocosBridgeModules.java +9 -0
- package/native/android/src/main/java/com/ft/sdk/cocos/FTCocosBridgeProvider.java +1 -1
- package/native/ios/FTCocosBridge.m +0 -202
- package/native/ios/FTCocosBridge.podspec +2 -3
- package/native/ios/Package.swift +1 -2
- package/package.json +10 -5
- package/plugin-api/package.json +4 -0
- package/components/creator2/ReplayPrivacy.ts +0 -23
- package/components/creator3/ReplayPrivacy.ts +0 -25
- package/dist/creator2/core/replay-async-transport.d.ts +0 -4
- package/dist/creator2/core/replay-async-transport.d.ts.map +0 -1
- package/dist/creator2/core/replay-async-transport.js +0 -67
- package/dist/creator2/core/replay-async-transport.js.map +0 -1
- package/dist/creator2/core/replay-budget.d.ts +0 -28
- package/dist/creator2/core/replay-budget.d.ts.map +0 -1
- package/dist/creator2/core/replay-budget.js +0 -113
- package/dist/creator2/core/replay-budget.js.map +0 -1
- package/dist/creator2/core/replay-diagnostics.d.ts +0 -36
- package/dist/creator2/core/replay-diagnostics.d.ts.map +0 -1
- package/dist/creator2/core/replay-diagnostics.js +0 -40
- package/dist/creator2/core/replay-diagnostics.js.map +0 -1
- package/dist/creator2/core/replay-encoding.d.ts +0 -31
- package/dist/creator2/core/replay-encoding.d.ts.map +0 -1
- package/dist/creator2/core/replay-encoding.js +0 -63
- package/dist/creator2/core/replay-encoding.js.map +0 -1
- package/dist/creator2/core/replay-file.d.ts +0 -5
- package/dist/creator2/core/replay-file.d.ts.map +0 -1
- package/dist/creator2/core/replay-file.js +0 -101
- package/dist/creator2/core/replay-file.js.map +0 -1
- package/dist/creator2/core/replay-pixels.d.ts +0 -3
- package/dist/creator2/core/replay-pixels.d.ts.map +0 -1
- package/dist/creator2/core/replay-pixels.js +0 -16
- package/dist/creator2/core/replay-pixels.js.map +0 -1
- package/dist/creator2/core/replay-privacy-nodes.d.ts +0 -14
- package/dist/creator2/core/replay-privacy-nodes.d.ts.map +0 -1
- package/dist/creator2/core/replay-privacy-nodes.js +0 -18
- package/dist/creator2/core/replay-privacy-nodes.js.map +0 -1
- package/dist/creator2/core/replay-privacy.d.ts +0 -15
- package/dist/creator2/core/replay-privacy.d.ts.map +0 -1
- package/dist/creator2/core/replay-privacy.js +0 -36
- package/dist/creator2/core/replay-privacy.js.map +0 -1
- package/dist/creator2/core/replay.d.ts +0 -99
- package/dist/creator2/core/replay.d.ts.map +0 -1
- package/dist/creator2/core/replay.js +0 -611
- package/dist/creator2/core/replay.js.map +0 -1
- package/dist/creator2/creator2/capture.d.ts +0 -17
- package/dist/creator2/creator2/capture.d.ts.map +0 -1
- package/dist/creator2/creator2/capture.js +0 -168
- package/dist/creator2/creator2/capture.js.map +0 -1
- package/dist/creator3/core/replay-async-transport.d.ts +0 -4
- package/dist/creator3/core/replay-async-transport.d.ts.map +0 -1
- package/dist/creator3/core/replay-async-transport.js +0 -16
- package/dist/creator3/core/replay-async-transport.js.map +0 -1
- package/dist/creator3/core/replay-budget.d.ts +0 -28
- package/dist/creator3/core/replay-budget.d.ts.map +0 -1
- package/dist/creator3/core/replay-budget.js +0 -105
- package/dist/creator3/core/replay-budget.js.map +0 -1
- package/dist/creator3/core/replay-diagnostics.d.ts +0 -36
- package/dist/creator3/core/replay-diagnostics.d.ts.map +0 -1
- package/dist/creator3/core/replay-diagnostics.js +0 -36
- package/dist/creator3/core/replay-diagnostics.js.map +0 -1
- package/dist/creator3/core/replay-encoding.d.ts +0 -31
- package/dist/creator3/core/replay-encoding.d.ts.map +0 -1
- package/dist/creator3/core/replay-encoding.js +0 -62
- package/dist/creator3/core/replay-encoding.js.map +0 -1
- package/dist/creator3/core/replay-file.d.ts +0 -5
- package/dist/creator3/core/replay-file.d.ts.map +0 -1
- package/dist/creator3/core/replay-file.js +0 -31
- package/dist/creator3/core/replay-file.js.map +0 -1
- package/dist/creator3/core/replay-pixels.d.ts +0 -3
- package/dist/creator3/core/replay-pixels.d.ts.map +0 -1
- package/dist/creator3/core/replay-pixels.js +0 -13
- package/dist/creator3/core/replay-pixels.js.map +0 -1
- package/dist/creator3/core/replay-privacy-nodes.d.ts +0 -14
- package/dist/creator3/core/replay-privacy-nodes.d.ts.map +0 -1
- package/dist/creator3/core/replay-privacy-nodes.js +0 -15
- package/dist/creator3/core/replay-privacy-nodes.js.map +0 -1
- package/dist/creator3/core/replay-privacy.d.ts +0 -15
- package/dist/creator3/core/replay-privacy.d.ts.map +0 -1
- package/dist/creator3/core/replay-privacy.js +0 -33
- package/dist/creator3/core/replay-privacy.js.map +0 -1
- package/dist/creator3/core/replay.d.ts +0 -99
- package/dist/creator3/core/replay.d.ts.map +0 -1
- package/dist/creator3/core/replay.js +0 -534
- package/dist/creator3/core/replay.js.map +0 -1
- package/dist/creator3/creator3/capture.d.ts +0 -17
- package/dist/creator3/creator3/capture.d.ts.map +0 -1
- package/dist/creator3/creator3/capture.js +0 -112
- package/dist/creator3/creator3/capture.js.map +0 -1
- package/dist/creator3/creator3/replay-render-cycle.d.ts +0 -9
- package/dist/creator3/creator3/replay-render-cycle.d.ts.map +0 -1
- package/dist/creator3/creator3/replay-render-cycle.js +0 -12
- package/dist/creator3/creator3/replay-render-cycle.js.map +0 -1
- package/native/android/src/main/java/com/ft/sdk/cocos/FTCocosReplayImageJobs.java +0 -55
- package/native/ios/FTCocosReplayImageJobs.h +0 -11
- package/native/ios/FTCocosReplayImageJobs.m +0 -54
- package/native/shared/FTReplayFileBridge.h +0 -62
- package/native/shared/FTReplayFileWorker.h +0 -88
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#import "FTCocosBridge.h"
|
|
2
|
-
#import "FTCocosReplayImageJobs.h"
|
|
3
2
|
|
|
4
3
|
#import "FTMobileAgent.h"
|
|
5
4
|
#import "FTSDKConfig.h"
|
|
@@ -9,7 +8,6 @@
|
|
|
9
8
|
#import "FTExternalDataManager.h"
|
|
10
9
|
#import "FTResourceMetricsModel.h"
|
|
11
10
|
#import "FTResourceContentModel.h"
|
|
12
|
-
#import "FTSessionReplay.h"
|
|
13
11
|
#import <UIKit/UIKit.h>
|
|
14
12
|
#import <objc/message.h>
|
|
15
13
|
|
|
@@ -32,10 +30,6 @@
|
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
+ (id)dispatch:(NSString *)method arguments:(NSDictionary *)arguments {
|
|
35
|
-
if ([method isEqualToString:@"replay.beginSaveImage"]) return [self beginSaveImage:arguments];
|
|
36
|
-
if ([method isEqualToString:@"replay.pollSaveImage"]) {
|
|
37
|
-
return [FTCocosReplayImageJobs poll:[self requiredText:arguments key:@"job"]];
|
|
38
|
-
}
|
|
39
33
|
FTExternalDataManager *rum = [FTExternalDataManager sharedManager];
|
|
40
34
|
if ([method isEqualToString:@"hybrid.attach"]) {
|
|
41
35
|
[self ensureNativeHostInitialized];
|
|
@@ -43,12 +37,6 @@
|
|
|
43
37
|
if (sdkVersion.length > 0) {
|
|
44
38
|
[FTMobileAgent appendGlobalContext:@{ @"sdk_package_cocos": sdkVersion }];
|
|
45
39
|
}
|
|
46
|
-
if ([arguments[@"requiresReplay"] boolValue]) [self ensureHybridRecorderSwitch];
|
|
47
|
-
return nil;
|
|
48
|
-
}
|
|
49
|
-
if ([method isEqualToString:@"hybrid.setExternalRecorderActive"]) {
|
|
50
|
-
[self ensureNativeHostInitialized];
|
|
51
|
-
[self setExternalRecorderActive:[arguments[@"active"] boolValue]];
|
|
52
40
|
return nil;
|
|
53
41
|
}
|
|
54
42
|
if ([method isEqualToString:@"sdk.configure"]) {
|
|
@@ -187,97 +175,10 @@
|
|
|
187
175
|
NSString *key = [self text:arguments[@"resourceKey"]];
|
|
188
176
|
return key.length > 0 ? [rum getTraceHeaderWithKey:key url:url] : [rum getTraceHeaderWithUrl:url];
|
|
189
177
|
}
|
|
190
|
-
if ([method isEqualToString:@"replay.configure"]) {
|
|
191
|
-
FTSessionReplayConfig *config = [[FTSessionReplayConfig alloc] init];
|
|
192
|
-
[self ensureExternalReplayAPIForConfig:config];
|
|
193
|
-
if (arguments[@"sampleRate"]) config.sampleRate = [self percent:arguments[@"sampleRate"]];
|
|
194
|
-
if (arguments[@"sessionOnErrorSampleRate"]) config.sessionReplayOnErrorSampleRate = [self percent:arguments[@"sessionOnErrorSampleRate"]];
|
|
195
|
-
if ([[self text:arguments[@"touchPrivacy"]] isEqualToString:@"show"]) config.touchPrivacy = FTTouchPrivacyLevelShow;
|
|
196
|
-
SEL externalMode = NSSelectorFromString(@"setExternalRecorderMode:");
|
|
197
|
-
((void (*)(id, SEL, BOOL))objc_msgSend)(config, externalMode, YES);
|
|
198
|
-
[[FTRumSessionReplay sharedInstance] startWithSessionReplayConfig:config];
|
|
199
|
-
return nil;
|
|
200
|
-
}
|
|
201
|
-
if ([method isEqualToString:@"replay.getContext"]) {
|
|
202
|
-
return [self invokeReplayObjectSelector:NSSelectorFromString(@"currentExternalRUMContext")];
|
|
203
|
-
}
|
|
204
|
-
if ([method isEqualToString:@"replay.saveImage"]) {
|
|
205
|
-
NSData *rgba = [NSData dataWithContentsOfFile:[self requiredText:arguments key:@"path"]];
|
|
206
|
-
if (!rgba) [self fail:@"Unable to read replay RGBA file"];
|
|
207
|
-
NSData *png = [self pngDataFromRGBA:rgba
|
|
208
|
-
width:[arguments[@"width"] unsignedIntegerValue]
|
|
209
|
-
height:[arguments[@"height"] unsignedIntegerValue]];
|
|
210
|
-
if (!png) [self fail:@"Unable to encode replay image"];
|
|
211
|
-
return [self invokeReplayObjectSelector:NSSelectorFromString(@"saveExternalImageResourceData:mimeType:")
|
|
212
|
-
first:png
|
|
213
|
-
second:@"image/png"];
|
|
214
|
-
}
|
|
215
|
-
if ([method isEqualToString:@"replay.saveImageV2"]) {
|
|
216
|
-
NSUInteger width = [arguments[@"width"] unsignedIntegerValue];
|
|
217
|
-
NSUInteger height = [arguments[@"height"] unsignedIntegerValue];
|
|
218
|
-
NSData *rgba = [NSData dataWithContentsOfFile:[self requiredText:arguments key:@"path"]];
|
|
219
|
-
if (!rgba) [self fail:@"Unable to read replay RGBA file"];
|
|
220
|
-
UIImage *image = [self imageFromRGBA:rgba width:width height:height];
|
|
221
|
-
if (!image) [self fail:@"Unable to decode replay RGBA image"];
|
|
222
|
-
|
|
223
|
-
CGFloat quality = MIN(1.0, MAX(0.1, [arguments[@"quality"] doubleValue] ?: 0.45));
|
|
224
|
-
NSUInteger maxFrameBytes = [arguments[@"maxFrameBytes"] unsignedIntegerValue] ?: 40 * 1024;
|
|
225
|
-
UIImage *encodedImage = [self opaqueImageFromImage:image size:CGSizeMake(width, height)];
|
|
226
|
-
NSData *jpeg = UIImageJPEGRepresentation(encodedImage, quality);
|
|
227
|
-
if (jpeg.length > maxFrameBytes) {
|
|
228
|
-
quality = MAX(0.2, quality * 0.7);
|
|
229
|
-
jpeg = UIImageJPEGRepresentation(encodedImage, quality);
|
|
230
|
-
}
|
|
231
|
-
if (jpeg.length > maxFrameBytes && width > 1 && height > 1) {
|
|
232
|
-
width = MAX(1, (NSUInteger)floor(width * 0.75));
|
|
233
|
-
height = MAX(1, (NSUInteger)floor(height * 0.75));
|
|
234
|
-
encodedImage = [self opaqueImageFromImage:image size:CGSizeMake(width, height)];
|
|
235
|
-
jpeg = UIImageJPEGRepresentation(encodedImage, quality);
|
|
236
|
-
}
|
|
237
|
-
if (!jpeg || jpeg.length > maxFrameBytes) return @{ @"accepted": @NO };
|
|
238
|
-
|
|
239
|
-
NSString *resourceID = [self invokeReplayObjectSelector:NSSelectorFromString(@"saveExternalImageResourceData:mimeType:")
|
|
240
|
-
first:jpeg
|
|
241
|
-
second:@"image/jpeg"];
|
|
242
|
-
if (resourceID.length == 0) [self fail:@"Unable to save replay image resource"];
|
|
243
|
-
return @{
|
|
244
|
-
@"accepted": @YES,
|
|
245
|
-
@"resourceId": resourceID,
|
|
246
|
-
@"byteSize": @(jpeg.length),
|
|
247
|
-
@"width": @(width),
|
|
248
|
-
@"height": @(height),
|
|
249
|
-
@"mimeType": @"image/jpeg",
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
if ([method isEqualToString:@"replay.writeSegment"]) {
|
|
253
|
-
[self invokeReplayVoidSelector:NSSelectorFromString(@"writeExternalSegment:viewID:")
|
|
254
|
-
first:[self requiredText:arguments key:@"segment"]
|
|
255
|
-
second:[self requiredText:arguments key:@"viewId"]];
|
|
256
|
-
return nil;
|
|
257
|
-
}
|
|
258
|
-
if ([method isEqualToString:@"replay.setRecordCount"]) {
|
|
259
|
-
[self invokeReplayCountSelector:NSSelectorFromString(@"setExternalRecordCountForViewID:count:")
|
|
260
|
-
viewID:[self requiredText:arguments key:@"viewId"]
|
|
261
|
-
count:[arguments[@"count"] unsignedIntegerValue]];
|
|
262
|
-
return nil;
|
|
263
|
-
}
|
|
264
|
-
if ([method isEqualToString:@"replay.stop"]) return nil;
|
|
265
178
|
[self fail:[NSString stringWithFormat:@"Unknown bridge method: %@", method]];
|
|
266
179
|
return nil;
|
|
267
180
|
}
|
|
268
181
|
|
|
269
|
-
+ (NSString *)beginSaveImage:(NSDictionary *)arguments {
|
|
270
|
-
NSString *method = [self requiredText:arguments key:@"method"];
|
|
271
|
-
if (![method isEqualToString:@"replay.saveImage"] && ![method isEqualToString:@"replay.saveImageV2"]) {
|
|
272
|
-
[self fail:@"Unsupported asynchronous Replay method"];
|
|
273
|
-
}
|
|
274
|
-
NSDictionary *payload = [[self dictionary:arguments[@"arguments"]] copy];
|
|
275
|
-
if (!payload) [self fail:@"Replay image arguments are required"];
|
|
276
|
-
return [FTCocosReplayImageJobs beginWithWork:^NSString *{
|
|
277
|
-
return [self responseWithValue:[self dispatch:method arguments:payload] error:nil];
|
|
278
|
-
}];
|
|
279
|
-
}
|
|
280
|
-
|
|
281
182
|
+ (void)ensureNativeHostInitialized {
|
|
282
183
|
@try {
|
|
283
184
|
if (![FTMobileAgent sharedInstance]) {
|
|
@@ -288,19 +189,6 @@
|
|
|
288
189
|
}
|
|
289
190
|
}
|
|
290
191
|
|
|
291
|
-
+ (void)ensureHybridRecorderSwitch {
|
|
292
|
-
SEL selector = NSSelectorFromString(@"setExternalRecorderActive:");
|
|
293
|
-
if (![[FTRumSessionReplay sharedInstance] respondsToSelector:selector]) {
|
|
294
|
-
[self fail:@"iOS Session Replay does not support Hybrid recorder switching; upgrade the Native SDK"];
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
+ (void)setExternalRecorderActive:(BOOL)active {
|
|
299
|
-
[self ensureHybridRecorderSwitch];
|
|
300
|
-
SEL selector = NSSelectorFromString(@"setExternalRecorderActive:");
|
|
301
|
-
((void (*)(id, SEL, BOOL))objc_msgSend)([FTRumSessionReplay sharedInstance], selector, active);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
192
|
+ (void)addResource:(NSDictionary *)arguments manager:(FTExternalDataManager *)manager {
|
|
305
193
|
NSDictionary *input = [self dictionary:arguments[@"content"]] ?: @{};
|
|
306
194
|
NSURL *url = [NSURL URLWithString:[self text:input[@"url"]] ?: @""];
|
|
@@ -330,96 +218,6 @@
|
|
|
330
218
|
[manager addResourceWithKey:[self requiredText:arguments key:@"key"] metrics:metrics content:content];
|
|
331
219
|
}
|
|
332
220
|
|
|
333
|
-
+ (id)invokeReplayObjectSelector:(SEL)selector {
|
|
334
|
-
id target = [FTRumSessionReplay sharedInstance];
|
|
335
|
-
if (![target respondsToSelector:selector]) [self missingReplayAPI:selector];
|
|
336
|
-
return ((id (*)(id, SEL))objc_msgSend)(target, selector);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
+ (id)invokeReplayObjectSelector:(SEL)selector object:(id)object {
|
|
340
|
-
id target = [FTRumSessionReplay sharedInstance];
|
|
341
|
-
if (![target respondsToSelector:selector]) [self missingReplayAPI:selector];
|
|
342
|
-
return ((id (*)(id, SEL, id))objc_msgSend)(target, selector, object);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
+ (id)invokeReplayObjectSelector:(SEL)selector first:(id)first second:(id)second {
|
|
346
|
-
id target = [FTRumSessionReplay sharedInstance];
|
|
347
|
-
if (![target respondsToSelector:selector]) [self missingReplayAPI:selector];
|
|
348
|
-
return ((id (*)(id, SEL, id, id))objc_msgSend)(target, selector, first, second);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
+ (void)invokeReplayVoidSelector:(SEL)selector first:(id)first second:(id)second {
|
|
352
|
-
id target = [FTRumSessionReplay sharedInstance];
|
|
353
|
-
if (![target respondsToSelector:selector]) [self missingReplayAPI:selector];
|
|
354
|
-
((void (*)(id, SEL, id, id))objc_msgSend)(target, selector, first, second);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
+ (void)invokeReplayCountSelector:(SEL)selector viewID:(NSString *)viewID count:(NSUInteger)count {
|
|
358
|
-
id target = [FTRumSessionReplay sharedInstance];
|
|
359
|
-
if (![target respondsToSelector:selector]) [self missingReplayAPI:selector];
|
|
360
|
-
((void (*)(id, SEL, id, NSUInteger))objc_msgSend)(target, selector, viewID, count);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
+ (void)missingReplayAPI:(SEL)selector {
|
|
364
|
-
[self fail:[NSString stringWithFormat:@"FTMobileSDK lacks external Session Replay API %@; use the Cocos-compatible iOS SDK release", NSStringFromSelector(selector)]];
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
+ (void)ensureExternalReplayAPIForConfig:(FTSessionReplayConfig *)config {
|
|
368
|
-
SEL externalMode = NSSelectorFromString(@"setExternalRecorderMode:");
|
|
369
|
-
if (![config respondsToSelector:externalMode]) [self missingReplayAPI:externalMode];
|
|
370
|
-
|
|
371
|
-
id target = [FTRumSessionReplay sharedInstance];
|
|
372
|
-
NSArray<NSString *> *selectorNames = @[
|
|
373
|
-
@"currentExternalRUMContext",
|
|
374
|
-
@"saveExternalImageResourceData:mimeType:",
|
|
375
|
-
@"writeExternalSegment:viewID:",
|
|
376
|
-
@"setExternalRecordCountForViewID:count:",
|
|
377
|
-
];
|
|
378
|
-
for (NSString *name in selectorNames) {
|
|
379
|
-
SEL selector = NSSelectorFromString(name);
|
|
380
|
-
if (![target respondsToSelector:selector]) [self missingReplayAPI:selector];
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
+ (NSData *)pngDataFromRGBA:(NSData *)rgba width:(NSUInteger)width height:(NSUInteger)height {
|
|
385
|
-
UIImage *image = [self imageFromRGBA:rgba width:width height:height];
|
|
386
|
-
return image ? UIImagePNGRepresentation(image) : nil;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
+ (UIImage *)imageFromRGBA:(NSData *)rgba width:(NSUInteger)width height:(NSUInteger)height {
|
|
390
|
-
if (width == 0 || height == 0 || width > NSUIntegerMax / height / 4 || rgba.length < width * height * 4) {
|
|
391
|
-
return nil;
|
|
392
|
-
}
|
|
393
|
-
NSMutableData *pixels = [rgba mutableCopy];
|
|
394
|
-
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
395
|
-
CGContextRef context = CGBitmapContextCreate(pixels.mutableBytes,
|
|
396
|
-
width,
|
|
397
|
-
height,
|
|
398
|
-
8,
|
|
399
|
-
width * 4,
|
|
400
|
-
colorSpace,
|
|
401
|
-
(CGBitmapInfo)kCGBitmapByteOrderDefault |
|
|
402
|
-
(CGBitmapInfo)kCGImageAlphaPremultipliedLast);
|
|
403
|
-
CGColorSpaceRelease(colorSpace);
|
|
404
|
-
if (!context) return nil;
|
|
405
|
-
CGImageRef imageRef = CGBitmapContextCreateImage(context);
|
|
406
|
-
CGContextRelease(context);
|
|
407
|
-
if (!imageRef) return nil;
|
|
408
|
-
UIImage *image = [UIImage imageWithCGImage:imageRef];
|
|
409
|
-
CGImageRelease(imageRef);
|
|
410
|
-
return image;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
+ (UIImage *)opaqueImageFromImage:(UIImage *)image size:(CGSize)size {
|
|
414
|
-
UIGraphicsBeginImageContextWithOptions(size, YES, 1.0);
|
|
415
|
-
[[UIColor whiteColor] setFill];
|
|
416
|
-
UIRectFill(CGRectMake(0, 0, size.width, size.height));
|
|
417
|
-
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
|
418
|
-
UIImage *opaque = UIGraphicsGetImageFromCurrentImageContext();
|
|
419
|
-
UIGraphicsEndImageContext();
|
|
420
|
-
return opaque;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
221
|
+ (NSString *)responseWithValue:(id)value error:(NSString *)error {
|
|
424
222
|
NSMutableDictionary *response = [@{ @"ok": @(error == nil) } mutableCopy];
|
|
425
223
|
if (value) response[@"value"] = value;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
Pod::Spec.new do |s|
|
|
2
2
|
s.name = 'FTCocosBridge'
|
|
3
|
-
s.version = '0.1.0-alpha.
|
|
3
|
+
s.version = '0.1.0-alpha.6'
|
|
4
4
|
s.summary = 'CloudCare Mobile SDK native bridge for Cocos Creator.'
|
|
5
5
|
s.homepage = 'https://github.com/GuanceCloud/datakit-cocos'
|
|
6
6
|
s.license = { :type => 'Apache-2.0' }
|
|
7
7
|
s.author = { 'Guance Cloud' => 'support@guance.com' }
|
|
8
8
|
s.source = { :path => '.' }
|
|
9
9
|
s.platform = :ios, '12.0'
|
|
10
|
-
s.source_files = 'FTCocosBridge.{h,m}'
|
|
10
|
+
s.source_files = 'FTCocosBridge.{h,m}'
|
|
11
11
|
s.public_header_files = 'FTCocosBridge.h'
|
|
12
12
|
s.requires_arc = true
|
|
13
13
|
# Cocos resolves FTCocosBridge by class name at runtime, so no direct symbol
|
|
14
14
|
# reference would otherwise keep the Objective-C category/class in the app.
|
|
15
15
|
s.user_target_xcconfig = { 'OTHER_LDFLAGS' => '$(inherited) -ObjC' }
|
|
16
16
|
s.dependency 'GuanceSDK/Agent', '1.6.8-alpha.5'
|
|
17
|
-
s.dependency 'GuanceSDK/FTSessionReplay', '1.6.8-alpha.5'
|
|
18
17
|
end
|
package/native/ios/Package.swift
CHANGED
|
@@ -13,11 +13,10 @@ let package = Package(
|
|
|
13
13
|
name: "FTCocosBridge",
|
|
14
14
|
dependencies: [
|
|
15
15
|
.product(name: "GuanceSDK", package: "datakit-ios"),
|
|
16
|
-
.product(name: "GuanceSessionReplay", package: "datakit-ios"),
|
|
17
16
|
],
|
|
18
17
|
path: ".",
|
|
19
18
|
exclude: ["FTCocosBridge.podspec"],
|
|
20
|
-
sources: ["FTCocosBridge.m"
|
|
19
|
+
sources: ["FTCocosBridge.m"],
|
|
21
20
|
publicHeadersPath: "include",
|
|
22
21
|
cSettings: [.headerSearchPath(".")],
|
|
23
22
|
linkerSettings: [.linkedFramework("UIKit")]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcare/cocos-sdk",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.6",
|
|
4
4
|
"description": "Observability SDK integration for Cocos Creator 2.4 and 3.x",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Guance Cloud",
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
"guance",
|
|
18
18
|
"cocos-creator",
|
|
19
19
|
"rum",
|
|
20
|
-
"session-replay",
|
|
21
20
|
"observability"
|
|
22
21
|
],
|
|
23
22
|
"exports": {
|
|
@@ -31,19 +30,25 @@
|
|
|
31
30
|
"import": "./dist/creator3/creator3/index.js",
|
|
32
31
|
"default": "./dist/creator3/creator3/index.js"
|
|
33
32
|
},
|
|
34
|
-
"./package.json": "./package.json"
|
|
33
|
+
"./package.json": "./package.json",
|
|
34
|
+
"./plugin-api": {
|
|
35
|
+
"types": "./dist/creator2/core/plugin-api.d.ts",
|
|
36
|
+
"import": "./dist/creator3/core/plugin-api.js",
|
|
37
|
+
"require": "./dist/creator2/core/plugin-api.js",
|
|
38
|
+
"default": "./dist/creator2/core/plugin-api.js"
|
|
39
|
+
}
|
|
35
40
|
},
|
|
36
41
|
"files": [
|
|
37
42
|
"creator2",
|
|
38
43
|
"creator3",
|
|
39
44
|
"dist",
|
|
40
|
-
"components",
|
|
41
45
|
"extensions",
|
|
42
46
|
"native",
|
|
43
47
|
"bin",
|
|
44
48
|
"README.md",
|
|
45
49
|
"LICENSE",
|
|
46
|
-
"THIRD_PARTY_NOTICES"
|
|
50
|
+
"THIRD_PARTY_NOTICES",
|
|
51
|
+
"plugin-api"
|
|
47
52
|
],
|
|
48
53
|
"bin": {
|
|
49
54
|
"guance-cocos": "bin/cli.cjs"
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const { ccclass, property, menu, disallowMultiple } = cc._decorator;
|
|
2
|
-
|
|
3
|
-
export enum ReplayPrivacyMode {
|
|
4
|
-
Mask = 0,
|
|
5
|
-
Hide = 1,
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/** Attach to a node or prefab to protect its bounds in Session Replay. */
|
|
9
|
-
@ccclass('ReplayPrivacy')
|
|
10
|
-
@menu('Session Replay/ReplayPrivacy')
|
|
11
|
-
@disallowMultiple
|
|
12
|
-
export default class ReplayPrivacy extends cc.Component {
|
|
13
|
-
@property({
|
|
14
|
-
type: cc.Enum(ReplayPrivacyMode),
|
|
15
|
-
tooltip: 'Mask fills the Replay region gray; Hide fills it black. The live scene is unchanged.',
|
|
16
|
-
})
|
|
17
|
-
mode: ReplayPrivacyMode = ReplayPrivacyMode.Mask;
|
|
18
|
-
|
|
19
|
-
/** Read by the SDK during capture; independent of SDK initialization order. */
|
|
20
|
-
get replayPrivacyMode(): 'mask' | 'hide' {
|
|
21
|
-
return this.mode === ReplayPrivacyMode.Hide ? 'hide' : 'mask';
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { _decorator, Component, Enum } from 'cc';
|
|
2
|
-
|
|
3
|
-
const { ccclass, property, menu, disallowMultiple } = _decorator;
|
|
4
|
-
|
|
5
|
-
export enum ReplayPrivacyMode {
|
|
6
|
-
Mask = 0,
|
|
7
|
-
Hide = 1,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/** Attach to a node or prefab to protect its bounds in Session Replay. */
|
|
11
|
-
@ccclass('ReplayPrivacy')
|
|
12
|
-
@menu('Session Replay/ReplayPrivacy')
|
|
13
|
-
@disallowMultiple
|
|
14
|
-
export default class ReplayPrivacy extends Component {
|
|
15
|
-
@property({
|
|
16
|
-
type: Enum(ReplayPrivacyMode),
|
|
17
|
-
tooltip: 'Mask fills the Replay region gray; Hide fills it black. The live scene is unchanged.',
|
|
18
|
-
})
|
|
19
|
-
mode: ReplayPrivacyMode = ReplayPrivacyMode.Mask;
|
|
20
|
-
|
|
21
|
-
/** Read by the SDK during capture; independent of SDK initialization order. */
|
|
22
|
-
get replayPrivacyMode(): 'mask' | 'hide' {
|
|
23
|
-
return this.mode === ReplayPrivacyMode.Hide ? 'hide' : 'mask';
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { FTNativeTransport } from './transport.js';
|
|
2
|
-
/** Polls a single native worker without keeping a synchronous bridge call open. */
|
|
3
|
-
export declare function invokeReplayAsync<T>(transport: FTNativeTransport, method: string, payload?: unknown): Promise<T | undefined>;
|
|
4
|
-
//# sourceMappingURL=replay-async-transport.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"replay-async-transport.d.ts","sourceRoot":"","sources":["../../../../../src/core/replay-async-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,mFAAmF;AACnF,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CASlI"}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.invokeReplayAsync = invokeReplayAsync;
|
|
40
|
-
var transport_js_1 = require("./transport.js");
|
|
41
|
-
/** Polls a single native worker without keeping a synchronous bridge call open. */
|
|
42
|
-
function invokeReplayAsync(transport, method, payload) {
|
|
43
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
44
|
-
var job, result;
|
|
45
|
-
return __generator(this, function (_a) {
|
|
46
|
-
switch (_a.label) {
|
|
47
|
-
case 0:
|
|
48
|
-
job = transport.invoke('replay.beginSaveImage', { method: method, arguments: payload });
|
|
49
|
-
if (!job)
|
|
50
|
-
throw new Error('Rebuild the native bridge to enable asynchronous Replay encoding');
|
|
51
|
-
_a.label = 1;
|
|
52
|
-
case 1: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 16); })];
|
|
53
|
-
case 2:
|
|
54
|
-
_a.sent();
|
|
55
|
-
result = transport.invoke('replay.pollSaveImage', { job: job });
|
|
56
|
-
if (!result)
|
|
57
|
-
throw new Error('Replay encoding job is unavailable');
|
|
58
|
-
if (!result.pending)
|
|
59
|
-
return [2 /*return*/, (0, transport_js_1.parseTransportResponse)(result.response)];
|
|
60
|
-
_a.label = 3;
|
|
61
|
-
case 3: return [3 /*break*/, 1];
|
|
62
|
-
case 4: return [2 /*return*/];
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=replay-async-transport.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"replay-async-transport.js","sourceRoot":"","sources":["../../../../../src/core/replay-async-transport.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,8CASC;AAZD,+CAAwD;AAExD,mFAAmF;AACnF,SAAsB,iBAAiB,CAAI,SAA4B,EAAE,MAAc,EAAE,OAAiB;;;;;;oBAClG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAS,uBAAuB,EAAE,EAAE,MAAM,QAAA,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC9F,IAAI,CAAC,GAAG;wBAAE,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;;wBAE5F,qBAAM,IAAI,OAAO,CAAO,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAvB,CAAuB,CAAC,EAAA;;oBAA7D,SAA6D,CAAC;oBACxD,MAAM,GAAG,SAAS,CAAC,MAAM,CAA0C,sBAAsB,EAAE,EAAE,GAAG,KAAA,EAAE,CAAC,CAAC;oBAC1G,IAAI,CAAC,MAAM;wBAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;oBACnE,IAAI,CAAC,MAAM,CAAC,OAAO;wBAAE,sBAAO,IAAA,qCAAsB,EAAI,MAAM,CAAC,QAAQ,CAAC,EAAC;;;;;;;CAE1E"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { FTResolvedReplayImagePolicy } from './validation.js';
|
|
2
|
-
export declare const REPLAY_KEY_FRAME_BURST_BYTES: number;
|
|
3
|
-
export interface FTReplayCaptureDecision {
|
|
4
|
-
allowed: boolean;
|
|
5
|
-
compressionQuality: number;
|
|
6
|
-
maxImageDimension: number;
|
|
7
|
-
maxFrameBytes: number;
|
|
8
|
-
usedBytes: number;
|
|
9
|
-
priority: boolean;
|
|
10
|
-
reason?: 'budget' | 'throttle';
|
|
11
|
-
}
|
|
12
|
-
/** Rolling image budget. Segment and pointer bytes intentionally remain outside this controller. */
|
|
13
|
-
export declare class FTReplayBudget {
|
|
14
|
-
private readonly policy;
|
|
15
|
-
private entries;
|
|
16
|
-
private lastCaptureAttempt;
|
|
17
|
-
private burstKeys;
|
|
18
|
-
private pressure;
|
|
19
|
-
constructor(policy: FTResolvedReplayImagePolicy);
|
|
20
|
-
reset(): void;
|
|
21
|
-
decide(timestamp: number, priorityKey?: string): FTReplayCaptureDecision;
|
|
22
|
-
record(timestamp: number, byteSize: number, priorityKey?: string): void;
|
|
23
|
-
usedBytes(timestamp: number): number;
|
|
24
|
-
private prune;
|
|
25
|
-
private decision;
|
|
26
|
-
private updatePressure;
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=replay-budget.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"replay-budget.d.ts","sourceRoot":"","sources":["../../../../../src/core/replay-budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAInE,eAAO,MAAM,4BAA4B,QAAa,CAAC;AAOvD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;CAChC;AAED,oGAAoG;AACpG,qBAAa,cAAc;IAMb,OAAO,CAAC,QAAQ,CAAC,MAAM;IALnC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAA4D;gBAE/C,MAAM,EAAE,2BAA2B;IAEhE,KAAK,IAAI,IAAI;IAOb,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,uBAAuB;IA+BxE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAUvE,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAKpC,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,QAAQ;IA2BhB,OAAO,CAAC,cAAc;CA0BvB"}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.FTReplayBudget = exports.REPLAY_KEY_FRAME_BURST_BYTES = void 0;
|
|
15
|
-
var WINDOW_MS = 60000;
|
|
16
|
-
var THROTTLED_CAPTURE_INTERVAL_MS = 2000;
|
|
17
|
-
exports.REPLAY_KEY_FRAME_BURST_BYTES = 100 * 1024;
|
|
18
|
-
/** Rolling image budget. Segment and pointer bytes intentionally remain outside this controller. */
|
|
19
|
-
var FTReplayBudget = /** @class */ (function () {
|
|
20
|
-
function FTReplayBudget(policy) {
|
|
21
|
-
this.policy = policy;
|
|
22
|
-
this.entries = [];
|
|
23
|
-
this.burstKeys = [];
|
|
24
|
-
this.pressure = 'normal';
|
|
25
|
-
}
|
|
26
|
-
FTReplayBudget.prototype.reset = function () {
|
|
27
|
-
this.entries = [];
|
|
28
|
-
this.lastCaptureAttempt = undefined;
|
|
29
|
-
this.burstKeys = [];
|
|
30
|
-
this.pressure = 'normal';
|
|
31
|
-
};
|
|
32
|
-
FTReplayBudget.prototype.decide = function (timestamp, priorityKey) {
|
|
33
|
-
var used = this.usedBytes(timestamp);
|
|
34
|
-
var ratio = used / this.policy.maxBytesPerMinute;
|
|
35
|
-
this.updatePressure(ratio);
|
|
36
|
-
var hasBurst = priorityKey !== undefined && !this.burstKeys.includes(priorityKey);
|
|
37
|
-
if (ratio >= 1 && !hasBurst)
|
|
38
|
-
return this.decision(false, 0, used, hasBurst, 'budget');
|
|
39
|
-
if (this.policy.adaptiveCapture
|
|
40
|
-
&& this.pressure !== 'normal'
|
|
41
|
-
&& this.lastCaptureAttempt !== undefined
|
|
42
|
-
&& timestamp - this.lastCaptureAttempt < THROTTLED_CAPTURE_INTERVAL_MS
|
|
43
|
-
&& !hasBurst) {
|
|
44
|
-
return this.decision(false, 0, used, hasBurst, 'throttle');
|
|
45
|
-
}
|
|
46
|
-
this.lastCaptureAttempt = timestamp;
|
|
47
|
-
var normalRemaining = Math.max(0, this.policy.maxBytesPerMinute - used);
|
|
48
|
-
var available = normalRemaining + (hasBurst ? exports.REPLAY_KEY_FRAME_BURST_BYTES : 0);
|
|
49
|
-
var frameLimit = hasBurst
|
|
50
|
-
? Math.min(Math.max(this.policy.maxFrameBytes, exports.REPLAY_KEY_FRAME_BURST_BYTES), available)
|
|
51
|
-
: Math.min(this.policy.maxFrameBytes, available);
|
|
52
|
-
return this.decision(frameLimit >= 1024, frameLimit, used, hasBurst, frameLimit >= 1024 ? undefined : 'budget');
|
|
53
|
-
};
|
|
54
|
-
FTReplayBudget.prototype.record = function (timestamp, byteSize, priorityKey) {
|
|
55
|
-
if (!Number.isFinite(byteSize) || byteSize <= 0)
|
|
56
|
-
return;
|
|
57
|
-
this.prune(timestamp);
|
|
58
|
-
this.entries.push({ timestamp: timestamp, byteSize: Math.round(byteSize) });
|
|
59
|
-
if (priorityKey && !this.burstKeys.includes(priorityKey)) {
|
|
60
|
-
this.burstKeys.push(priorityKey);
|
|
61
|
-
if (this.burstKeys.length > 64)
|
|
62
|
-
this.burstKeys.shift();
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
FTReplayBudget.prototype.usedBytes = function (timestamp) {
|
|
66
|
-
this.prune(timestamp);
|
|
67
|
-
return this.entries.reduce(function (total, entry) { return total + entry.byteSize; }, 0);
|
|
68
|
-
};
|
|
69
|
-
FTReplayBudget.prototype.prune = function (timestamp) {
|
|
70
|
-
var cutoff = timestamp - WINDOW_MS;
|
|
71
|
-
while (this.entries.length > 0 && this.entries[0].timestamp <= cutoff)
|
|
72
|
-
this.entries.shift();
|
|
73
|
-
};
|
|
74
|
-
FTReplayBudget.prototype.decision = function (allowed, maxFrameBytes, usedBytes, priority, reason) {
|
|
75
|
-
var degraded = this.policy.adaptiveCapture
|
|
76
|
-
&& (this.pressure === 'degraded' || this.pressure === 'paused');
|
|
77
|
-
return __assign({ allowed: allowed, compressionQuality: degraded
|
|
78
|
-
? Math.max(0.25, Math.round(this.policy.compressionQuality * 0.75 * 100) / 100)
|
|
79
|
-
: this.policy.compressionQuality, maxImageDimension: degraded
|
|
80
|
-
? Math.min(this.policy.maxImageDimension, Math.max(240, Math.floor(this.policy.maxImageDimension * 0.75)))
|
|
81
|
-
: this.policy.maxImageDimension, maxFrameBytes: Math.max(0, Math.floor(maxFrameBytes)), usedBytes: usedBytes, priority: priority }, (reason ? { reason: reason } : {}));
|
|
82
|
-
};
|
|
83
|
-
FTReplayBudget.prototype.updatePressure = function (ratio) {
|
|
84
|
-
if (!this.policy.adaptiveCapture) {
|
|
85
|
-
this.pressure = 'normal';
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if (ratio >= 1) {
|
|
89
|
-
this.pressure = 'paused';
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
if (ratio >= 0.9) {
|
|
93
|
-
this.pressure = 'degraded';
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (this.pressure === 'paused' || this.pressure === 'degraded') {
|
|
97
|
-
if (ratio >= 0.8) {
|
|
98
|
-
this.pressure = 'degraded';
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (ratio >= 0.75) {
|
|
103
|
-
this.pressure = 'throttled';
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
if (this.pressure === 'throttled' && ratio >= 0.65)
|
|
107
|
-
return;
|
|
108
|
-
this.pressure = 'normal';
|
|
109
|
-
};
|
|
110
|
-
return FTReplayBudget;
|
|
111
|
-
}());
|
|
112
|
-
exports.FTReplayBudget = FTReplayBudget;
|
|
113
|
-
//# sourceMappingURL=replay-budget.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"replay-budget.js","sourceRoot":"","sources":["../../../../../src/core/replay-budget.ts"],"names":[],"mappings":"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"}
|