@cloudcare/cocos-sdk 0.1.0-alpha.3 → 0.1.0-alpha.5

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.
Files changed (77) hide show
  1. package/README.md +37 -1
  2. package/bin/cli.cjs +14 -0
  3. package/components/creator2/ReplayPrivacy.ts +23 -0
  4. package/components/creator3/ReplayPrivacy.ts +25 -0
  5. package/dist/creator2/core/replay-async-transport.d.ts +4 -0
  6. package/dist/creator2/core/replay-async-transport.d.ts.map +1 -0
  7. package/dist/creator2/core/replay-async-transport.js +67 -0
  8. package/dist/creator2/core/replay-async-transport.js.map +1 -0
  9. package/dist/creator2/core/replay-file.d.ts +5 -0
  10. package/dist/creator2/core/replay-file.d.ts.map +1 -0
  11. package/dist/creator2/core/replay-file.js +101 -0
  12. package/dist/creator2/core/replay-file.js.map +1 -0
  13. package/dist/creator2/core/replay-privacy-nodes.d.ts +14 -0
  14. package/dist/creator2/core/replay-privacy-nodes.d.ts.map +1 -0
  15. package/dist/creator2/core/replay-privacy-nodes.js +18 -0
  16. package/dist/creator2/core/replay-privacy-nodes.js.map +1 -0
  17. package/dist/creator2/core/replay.d.ts +5 -3
  18. package/dist/creator2/core/replay.d.ts.map +1 -1
  19. package/dist/creator2/core/replay.js +74 -41
  20. package/dist/creator2/core/replay.js.map +1 -1
  21. package/dist/creator2/core/transport.d.ts +1 -0
  22. package/dist/creator2/core/transport.d.ts.map +1 -1
  23. package/dist/creator2/core/transport.js.map +1 -1
  24. package/dist/creator2/core/version.d.ts +1 -1
  25. package/dist/creator2/core/version.js +1 -1
  26. package/dist/creator2/creator2/capture.d.ts +1 -1
  27. package/dist/creator2/creator2/capture.d.ts.map +1 -1
  28. package/dist/creator2/creator2/capture.js +9 -16
  29. package/dist/creator2/creator2/capture.js.map +1 -1
  30. package/dist/creator2/creator2/transport.d.ts +1 -0
  31. package/dist/creator2/creator2/transport.d.ts.map +1 -1
  32. package/dist/creator2/creator2/transport.js +4 -0
  33. package/dist/creator2/creator2/transport.js.map +1 -1
  34. package/dist/creator3/core/replay-async-transport.d.ts +4 -0
  35. package/dist/creator3/core/replay-async-transport.d.ts.map +1 -0
  36. package/dist/creator3/core/replay-async-transport.js +16 -0
  37. package/dist/creator3/core/replay-async-transport.js.map +1 -0
  38. package/dist/creator3/core/replay-file.d.ts +5 -0
  39. package/dist/creator3/core/replay-file.d.ts.map +1 -0
  40. package/dist/creator3/core/replay-file.js +31 -0
  41. package/dist/creator3/core/replay-file.js.map +1 -0
  42. package/dist/creator3/core/replay-privacy-nodes.d.ts +14 -0
  43. package/dist/creator3/core/replay-privacy-nodes.d.ts.map +1 -0
  44. package/dist/creator3/core/replay-privacy-nodes.js +15 -0
  45. package/dist/creator3/core/replay-privacy-nodes.js.map +1 -0
  46. package/dist/creator3/core/replay.d.ts +5 -3
  47. package/dist/creator3/core/replay.d.ts.map +1 -1
  48. package/dist/creator3/core/replay.js +23 -9
  49. package/dist/creator3/core/replay.js.map +1 -1
  50. package/dist/creator3/core/transport.d.ts +1 -0
  51. package/dist/creator3/core/transport.d.ts.map +1 -1
  52. package/dist/creator3/core/transport.js.map +1 -1
  53. package/dist/creator3/core/version.d.ts +1 -1
  54. package/dist/creator3/core/version.js +1 -1
  55. package/dist/creator3/creator3/capture.d.ts +1 -1
  56. package/dist/creator3/creator3/capture.d.ts.map +1 -1
  57. package/dist/creator3/creator3/capture.js +6 -13
  58. package/dist/creator3/creator3/capture.js.map +1 -1
  59. package/dist/creator3/creator3/transport.d.ts +1 -0
  60. package/dist/creator3/creator3/transport.d.ts.map +1 -1
  61. package/dist/creator3/creator3/transport.js +4 -0
  62. package/dist/creator3/creator3/transport.js.map +1 -1
  63. package/extensions/creator2/install-native.cjs +126 -6
  64. package/extensions/creator2/install-spm.cjs +190 -0
  65. package/extensions/creator3/install-native.cjs +126 -6
  66. package/extensions/creator3/install-spm.cjs +190 -0
  67. package/native/android/src/main/java/com/ft/sdk/cocos/FTCocosBridge.java +4 -0
  68. package/native/android/src/main/java/com/ft/sdk/cocos/FTCocosReplayImageJobs.java +55 -0
  69. package/native/ios/FTCocosBridge.m +26 -2
  70. package/native/ios/FTCocosBridge.podspec +4 -4
  71. package/native/ios/FTCocosReplayImageJobs.h +11 -0
  72. package/native/ios/FTCocosReplayImageJobs.m +54 -0
  73. package/native/ios/Package.swift +26 -0
  74. package/native/ios/include/FTCocosBridge.h +2 -0
  75. package/native/shared/FTReplayFileBridge.h +62 -0
  76. package/native/shared/FTReplayFileWorker.h +88 -0
  77. package/package.json +2 -1
package/README.md CHANGED
@@ -18,13 +18,49 @@ Guance Cloud Application Monitoring collects and analyzes RUM, Log, Trace, and S
18
18
 
19
19
  Cocos Creator 3.0–3.6.2 is supported on a best-effort basis because the stable native build extension API starts at 3.6.3. Web, mini-game, and desktop targets are not currently supported.
20
20
 
21
+ ## iOS dependency manager
22
+
23
+ CocoaPods remains the default. To use Swift Package Manager, add
24
+ `cocos-sdk.config.json` to your **Cocos project root** (beside `assets`):
25
+
26
+ ```json
27
+ {
28
+ "ios": {
29
+ "dependencyManager": "spm"
30
+ }
31
+ }
32
+ ```
33
+
34
+ Alternatively, save this setting when installing the extension:
35
+
36
+ ```sh
37
+ npx @cloudcare/cocos-sdk install --ios-dependency-manager spm
38
+ ```
39
+
40
+ Rebuild the native iOS project in Creator after changing the configuration. The
41
+ extension links the local `FTCocosBridge` package and Xcode resolves the pinned
42
+ iOS SDK from Git. Fresh SPM projects do not require `pod install`; open the
43
+ `.xcodeproj`. If the host uses CocoaPods for other libraries, continue opening
44
+ its `.xcworkspace`.
45
+
46
+ When switching an existing installation, the extension removes its managed SDK
47
+ Pod entries and runs `pod install` if Pods were previously installed. Other Pods
48
+ are preserved. Manually declared SDK Pods or other Pods that depend on the same
49
+ native SDK must be migrated first to avoid duplicate linking. Set the value to
50
+ `cocoapods` to switch back, then run `pod install` as usual.
51
+
52
+ Creator 3 CMake regeneration restores the package integration automatically during
53
+ Xcode builds. If you regenerate the project by running CMake separately, rerun
54
+ Creator's native build integration before opening Xcode. Hybrid examples use the
55
+ same configuration with their existing `native:install` command.
56
+
21
57
  ## Examples
22
58
 
23
59
  [Guance Cloud SDK Cocos Creator Demo](https://github.com/GuanceCloud/datakit-cocos/tree/main/examples)
24
60
 
25
61
  ## Documentation
26
62
 
27
- [Documentation Center](https://docs.guance.com/real-user-monitoring/cocos/app-access/)
63
+ For installation, configuration, and usage, see the [official documentation](https://docs.guance.com/real-user-monitoring/cocos/app-access/).
28
64
 
29
65
  ## License
30
66
 
package/bin/cli.cjs CHANGED
@@ -28,12 +28,25 @@ const container = creatorMajor === 2 ? 'packages' : 'extensions';
28
28
  const destination = path.join(projectRoot, container, 'guance-cocos-sdk');
29
29
  const legacyDestination = path.join(projectRoot, container, 'ft-cocos-sdk');
30
30
  const extensionSource = path.join(packageRoot, 'extensions', `creator${creatorMajor}`);
31
+ const manager = readOption(rawArguments, '--ios-dependency-manager');
32
+ if (manager !== undefined && !['spm', 'cocoapods'].includes(manager)) {
33
+ fail('Invalid --ios-dependency-manager. Expected spm or cocoapods.');
34
+ }
35
+ const configFile = path.join(projectRoot, 'cocos-sdk.config.json');
36
+ const config = readJson(configFile) || {};
37
+ if (manager !== undefined) {
38
+ config.ios = { ...config.ios, dependencyManager: manager };
39
+ fs.writeFileSync(configFile, `${JSON.stringify(config, null, 2)}\n`);
40
+ }
31
41
 
32
42
  copyDirectory(extensionSource, destination);
33
43
  copyDirectory(path.join(packageRoot, 'native'), path.join(destination, 'native'));
44
+ const componentDestination = path.join(projectRoot, 'assets', 'guance-cocos-sdk');
45
+ copyDirectory(path.join(packageRoot, 'components', `creator${creatorMajor}`), componentDestination);
34
46
 
35
47
  process.stdout.write(
36
48
  `Installed ${metadata.name} for Cocos Creator ${creatorMajor} at ${destination}\n`
49
+ + `Installed ReplayPrivacy at ${componentDestination}. Add it through Session Replay/ReplayPrivacy in the component menu.\n`
37
50
  + 'Re-open Cocos Creator, enable the guance-cocos-sdk extension, and rebuild the native project.\n',
38
51
  );
39
52
  if (fs.existsSync(legacyDestination)) {
@@ -116,6 +129,7 @@ function printHelp() {
116
129
  'Options:',
117
130
  ' --project <path> Cocos project root (defaults to the current directory)',
118
131
  ' --creator <2|3> Override automatic Cocos Creator version detection',
132
+ ' --ios-dependency-manager <spm|cocoapods> Save the iOS dependency manager in cocos-sdk.config.json',
119
133
  ' -h, --help Show this help',
120
134
  '',
121
135
  ].join('\n'));
@@ -0,0 +1,23 @@
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
+ }
@@ -0,0 +1,25 @@
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
+ }
@@ -0,0 +1,4 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,67 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,5 @@
1
+ import type { FTCapturedFrame, FTStoredFrame } from './types.js';
2
+ /** Copies pixels into native-owned memory; all file operations run off the game thread. */
3
+ export declare function persistReplayFrame(frame: FTCapturedFrame, fingerprint: string, writablePath: string): Promise<FTStoredFrame>;
4
+ export declare function disposeReplayFrame(frame: FTStoredFrame): Promise<void>;
5
+ //# sourceMappingURL=replay-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-file.d.ts","sourceRoot":"","sources":["../../../../../src/core/replay-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAwBjE,2FAA2F;AAC3F,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAKxB;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E"}
@@ -0,0 +1,101 @@
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.persistReplayFrame = persistReplayFrame;
40
+ exports.disposeReplayFrame = disposeReplayFrame;
41
+ var sequence = 0;
42
+ function bridge() {
43
+ var value = globalThis.__ftCocosReplayFile;
44
+ if (!value)
45
+ throw new Error('Rebuild the native project with the Cocos SDK extension to enable asynchronous Replay storage');
46
+ return value;
47
+ }
48
+ function waitForFile(expected) {
49
+ return __awaiter(this, void 0, void 0, function () {
50
+ var status_1;
51
+ return __generator(this, function (_a) {
52
+ switch (_a.label) {
53
+ case 0: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 16); })];
54
+ case 1:
55
+ _a.sent();
56
+ status_1 = bridge().poll();
57
+ if (status_1 === expected)
58
+ return [2 /*return*/];
59
+ if (status_1 !== 'pending')
60
+ throw new Error("Replay file operation failed: ".concat(status_1));
61
+ _a.label = 2;
62
+ case 2: return [3 /*break*/, 0];
63
+ case 3: return [2 /*return*/];
64
+ }
65
+ });
66
+ });
67
+ }
68
+ /** Copies pixels into native-owned memory; all file operations run off the game thread. */
69
+ function persistReplayFrame(frame, fingerprint, writablePath) {
70
+ return __awaiter(this, void 0, void 0, function () {
71
+ var path;
72
+ return __generator(this, function (_a) {
73
+ switch (_a.label) {
74
+ case 0:
75
+ path = "".concat(writablePath, "cocos-sdk-replay-").concat(Date.now(), "-").concat(++sequence, "-").concat(fingerprint, ".rgba");
76
+ if (!bridge().write(frame.rgba, path))
77
+ throw new Error('Replay file writer is busy');
78
+ return [4 /*yield*/, waitForFile('written')];
79
+ case 1:
80
+ _a.sent();
81
+ return [2 /*return*/, { path: path, width: frame.width, height: frame.height, timestamp: frame.timestamp, fingerprint: fingerprint }];
82
+ }
83
+ });
84
+ });
85
+ }
86
+ function disposeReplayFrame(frame) {
87
+ return __awaiter(this, void 0, void 0, function () {
88
+ return __generator(this, function (_a) {
89
+ switch (_a.label) {
90
+ case 0:
91
+ if (!bridge().remove(frame.path))
92
+ throw new Error('Replay file writer is busy or the frame has expired');
93
+ return [4 /*yield*/, waitForFile('removed')];
94
+ case 1:
95
+ _a.sent();
96
+ return [2 /*return*/];
97
+ }
98
+ });
99
+ });
100
+ }
101
+ //# sourceMappingURL=replay-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-file.js","sourceRoot":"","sources":["../../../../../src/core/replay-file.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,gDASC;AAED,gDAGC;AA/BD,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,SAAS,MAAM;IACb,IAAM,KAAK,GAAI,UAAsE,CAAC,mBAAmB,CAAC;IAC1G,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;IAC7H,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAe,WAAW,CAAC,QAA+B;;;;;wBAEtD,qBAAM,IAAI,OAAO,CAAO,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAvB,CAAuB,CAAC,EAAA;;oBAA7D,SAA6D,CAAC;oBACxD,WAAS,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;oBAC/B,IAAI,QAAM,KAAK,QAAQ;wBAAE,sBAAO;oBAChC,IAAI,QAAM,KAAK,SAAS;wBAAE,MAAM,IAAI,KAAK,CAAC,wCAAiC,QAAM,CAAE,CAAC,CAAC;;;;;;;CAExF;AAED,2FAA2F;AAC3F,SAAsB,kBAAkB,CACtC,KAAsB,EACtB,WAAmB,EACnB,YAAoB;;;;;;oBAEd,IAAI,GAAG,UAAG,YAAY,8BAAoB,IAAI,CAAC,GAAG,EAAE,cAAI,EAAE,QAAQ,cAAI,WAAW,UAAO,CAAC;oBAC/F,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;wBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;oBACrF,qBAAM,WAAW,CAAC,SAAS,CAAC,EAAA;;oBAA5B,SAA4B,CAAC;oBAC7B,sBAAO,EAAE,IAAI,MAAA,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,aAAA,EAAE,EAAC;;;;CACpG;AAED,SAAsB,kBAAkB,CAAC,KAAoB;;;;;oBAC3D,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;wBAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;oBACzG,qBAAM,WAAW,CAAC,SAAS,CAAC,EAAA;;oBAA5B,SAA4B,CAAC;;;;;CAC9B"}
@@ -0,0 +1,14 @@
1
+ import type { FTReplayPrivacyMode } from './types.js';
2
+ /** Shape of the ReplayPrivacy editor script installed in the project's assets. */
3
+ interface ReplayPrivacyComponent {
4
+ node: unknown;
5
+ enabledInHierarchy: boolean;
6
+ isValid: boolean;
7
+ readonly replayPrivacyMode: 'mask' | 'hide';
8
+ }
9
+ /** Resolve rules afresh for each capture, including newly instantiated prefabs. */
10
+ export declare function collectReplayPrivacyNodes(overrides: ReadonlyMap<unknown, FTReplayPrivacyMode>, components: ReplayPrivacyComponent[], editBoxes: {
11
+ node: unknown;
12
+ }[]): Map<unknown, FTReplayPrivacyMode>;
13
+ export {};
14
+ //# sourceMappingURL=replay-privacy-nodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-privacy-nodes.d.ts","sourceRoot":"","sources":["../../../../../src/core/replay-privacy-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,kFAAkF;AAClF,UAAU,sBAAsB;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7C;AAED,mFAAmF;AACnF,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,mBAAmB,CAAC,EACpD,UAAU,EAAE,sBAAsB,EAAE,EACpC,SAAS,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,GAC7B,GAAG,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAUnC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectReplayPrivacyNodes = collectReplayPrivacyNodes;
4
+ /** Resolve rules afresh for each capture, including newly instantiated prefabs. */
5
+ function collectReplayPrivacyNodes(overrides, components, editBoxes) {
6
+ var nodes = new Map(overrides);
7
+ components.forEach(function (component) {
8
+ if (!component.isValid || !component.enabledInHierarchy || nodes.has(component.node))
9
+ return;
10
+ nodes.set(component.node, component.replayPrivacyMode === 'hide' ? 'hide' : 'mask');
11
+ });
12
+ editBoxes.forEach(function (editBox) {
13
+ if (!nodes.has(editBox.node))
14
+ nodes.set(editBox.node, 'mask');
15
+ });
16
+ return nodes;
17
+ }
18
+ //# sourceMappingURL=replay-privacy-nodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-privacy-nodes.js","sourceRoot":"","sources":["../../../../../src/core/replay-privacy-nodes.ts"],"names":[],"mappings":";;AAWA,8DAcC;AAfD,mFAAmF;AACnF,SAAgB,yBAAyB,CACvC,SAAoD,EACpD,UAAoC,EACpC,SAA8B;IAE9B,IAAM,KAAK,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IACjC,UAAU,CAAC,OAAO,CAAC,UAAC,SAAS;QAC3B,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,kBAAkB,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC;YAAE,OAAO;QAC7F,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,OAAO,CAAC,UAAC,OAAO;QACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -7,7 +7,7 @@ export interface FTCanvasCapture {
7
7
  } | undefined;
8
8
  capture(maxImageDimension: number): Promise<FTCapturedFrame | undefined>;
9
9
  persist(frame: FTCapturedFrame, fingerprint: string): Promise<FTStoredFrame>;
10
- disposeStoredFrame(frame: FTStoredFrame): void;
10
+ disposeStoredFrame(frame: FTStoredFrame): void | Promise<void>;
11
11
  setPrivacy(node: unknown, mode: 'mask' | 'hide' | 'unmask'): void;
12
12
  }
13
13
  export interface FTReplayPointerEvent {
@@ -73,8 +73,9 @@ export declare class FTSessionReplay {
73
73
  * Changes the Session Replay privacy treatment for a Cocos node.
74
74
  *
75
75
  * `mask` obscures the node, `hide` removes the region from the replay, and
76
- * `unmask` clears an earlier override. The node must belong to the active
77
- * Cocos scene.
76
+ * `unmask` clears an earlier code override, restoring any ReplayPrivacy
77
+ * component rule or default input masking. Code overrides take priority over
78
+ * a component on the same node. The node must belong to the active Cocos scene.
78
79
  *
79
80
  * @param node - Cocos node whose rendered bounds receive the privacy rule.
80
81
  * @param mode - Privacy treatment to apply.
@@ -85,6 +86,7 @@ export declare class FTSessionReplay {
85
86
  private schedule;
86
87
  private readContext;
87
88
  private saveImage;
89
+ private invokeSaveImage;
88
90
  private writePendingPointers;
89
91
  private scaledPendingPointers;
90
92
  private updateRecordCount;
@@ -1 +1 @@
1
- {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../../../../src/core/replay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../../../../src/core/replay.ts"],"names":[],"mappings":"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"}
@@ -160,8 +160,9 @@ var FTSessionReplay = /** @class */ (function () {
160
160
  * Changes the Session Replay privacy treatment for a Cocos node.
161
161
  *
162
162
  * `mask` obscures the node, `hide` removes the region from the replay, and
163
- * `unmask` clears an earlier override. The node must belong to the active
164
- * Cocos scene.
163
+ * `unmask` clears an earlier code override, restoring any ReplayPrivacy
164
+ * component rule or default input masking. Code overrides take priority over
165
+ * a component on the same node. The node must belong to the active Cocos scene.
165
166
  *
166
167
  * @param node - Cocos node whose rendered bounds receive the privacy rule.
167
168
  * @param mode - Privacy treatment to apply.
@@ -186,7 +187,7 @@ var FTSessionReplay = /** @class */ (function () {
186
187
  pointerSize = this.lastImageSize;
187
188
  _c.label = 1;
188
189
  case 1:
189
- _c.trys.push([1, 4, 5, 6]);
190
+ _c.trys.push([1, 5, 6, 11]);
190
191
  context = this.readContext();
191
192
  if (!context)
192
193
  return [2 /*return*/, false];
@@ -250,7 +251,11 @@ var FTSessionReplay = /** @class */ (function () {
250
251
  stored = _c.sent();
251
252
  if (generation !== this.captureGeneration)
252
253
  return [2 /*return*/, false];
253
- saved = this.saveImage(stored, decision.compressionQuality, decision.maxFrameBytes);
254
+ return [4 /*yield*/, this.saveImage(stored, decision.compressionQuality, decision.maxFrameBytes)];
255
+ case 4:
256
+ saved = _c.sent();
257
+ if (generation !== this.captureGeneration)
258
+ return [2 /*return*/, false];
254
259
  if (!saved) {
255
260
  (0, replay_diagnostics_js_1.emitReplayDiagnostic)({ type: 'capture_skipped', timestamp: now, reason: 'budget' });
256
261
  return [2 /*return*/, this.writePendingPointers(context, frame.width, frame.height)];
@@ -280,8 +285,10 @@ var FTSessionReplay = /** @class */ (function () {
280
285
  this.lastImageSize = { width: saved.width, height: saved.height };
281
286
  this.lastViewportSize = viewportSize;
282
287
  return [2 /*return*/, true];
283
- case 4:
288
+ case 5:
284
289
  error_1 = _c.sent();
290
+ if (generation !== this.captureGeneration)
291
+ return [2 /*return*/, false];
285
292
  (0, replay_diagnostics_js_1.emitReplayDiagnostic)({ type: 'capture_skipped', timestamp: Date.now(), reason: 'error' });
286
293
  console.error('[cocos-sdk] Session Replay frame dropped:', error_1);
287
294
  if (context && pointerSize) {
@@ -293,12 +300,19 @@ var FTSessionReplay = /** @class */ (function () {
293
300
  }
294
301
  }
295
302
  return [2 /*return*/, false];
296
- case 5:
297
- if (stored)
298
- this.capture.disposeStoredFrame(stored);
303
+ case 6:
304
+ _c.trys.push([6, , 9, 10]);
305
+ if (!stored) return [3 /*break*/, 8];
306
+ return [4 /*yield*/, this.capture.disposeStoredFrame(stored)];
307
+ case 7:
308
+ _c.sent();
309
+ _c.label = 8;
310
+ case 8: return [3 /*break*/, 10];
311
+ case 9:
299
312
  this.busy = false;
300
313
  return [7 /*endfinally*/];
301
- case 6: return [2 /*return*/];
314
+ case 10: return [7 /*endfinally*/];
315
+ case 11: return [2 /*return*/];
302
316
  }
303
317
  });
304
318
  });
@@ -382,40 +396,59 @@ var FTSessionReplay = /** @class */ (function () {
382
396
  return normalizeRumContext(value);
383
397
  };
384
398
  FTSessionReplay.prototype.saveImage = function (stored, compressionQuality, maxFrameBytes) {
385
- if (this.imagePolicyEnabled && this.supportsSaveImageV2 !== false) {
386
- try {
387
- var value = this.transport.invoke('replay.saveImageV2', {
388
- path: stored.path,
389
- width: stored.width,
390
- height: stored.height,
391
- quality: compressionQuality,
392
- maxFrameBytes: maxFrameBytes,
393
- });
394
- if (value !== undefined) {
395
- this.supportsSaveImageV2 = true;
396
- if (isRejectedSaveImageV2(value))
397
- return undefined;
398
- return __assign(__assign({}, normalizeSaveImageV2Result(value)), { byteSizeSource: 'native' });
399
+ return __awaiter(this, void 0, void 0, function () {
400
+ var value, error_3, resourceId;
401
+ return __generator(this, function (_a) {
402
+ switch (_a.label) {
403
+ case 0:
404
+ if (!(this.imagePolicyEnabled && this.supportsSaveImageV2 !== false)) return [3 /*break*/, 4];
405
+ _a.label = 1;
406
+ case 1:
407
+ _a.trys.push([1, 3, , 4]);
408
+ return [4 /*yield*/, this.invokeSaveImage('replay.saveImageV2', {
409
+ path: stored.path,
410
+ width: stored.width,
411
+ height: stored.height,
412
+ quality: compressionQuality,
413
+ maxFrameBytes: maxFrameBytes,
414
+ })];
415
+ case 2:
416
+ value = _a.sent();
417
+ if (value !== undefined) {
418
+ this.supportsSaveImageV2 = true;
419
+ if (isRejectedSaveImageV2(value))
420
+ return [2 /*return*/, undefined];
421
+ return [2 /*return*/, __assign(__assign({}, normalizeSaveImageV2Result(value)), { byteSizeSource: 'native' })];
422
+ }
423
+ this.supportsSaveImageV2 = false;
424
+ return [3 /*break*/, 4];
425
+ case 3:
426
+ error_3 = _a.sent();
427
+ if (!isUnknownBridgeMethod(error_3))
428
+ throw error_3;
429
+ this.supportsSaveImageV2 = false;
430
+ return [3 /*break*/, 4];
431
+ case 4: return [4 /*yield*/, this.invokeSaveImage('replay.saveImage', {
432
+ path: stored.path,
433
+ width: stored.width,
434
+ height: stored.height,
435
+ })];
436
+ case 5:
437
+ resourceId = _a.sent();
438
+ if (!resourceId)
439
+ return [2 /*return*/, undefined];
440
+ return [2 /*return*/, __assign({ resourceId: resourceId,
441
+ // V1 cannot report encoded size. A conservative frame-limit estimate
442
+ // still prevents configured captureFps from multiplying traffic freely.
443
+ byteSize: maxFrameBytes, width: stored.width, height: stored.height, byteSizeSource: 'frame_limit_estimate' }, (this.transport.platform === 'ios' ? { mimeType: 'image/png' } : {}))];
399
444
  }
400
- this.supportsSaveImageV2 = false;
401
- }
402
- catch (error) {
403
- if (!isUnknownBridgeMethod(error))
404
- throw error;
405
- this.supportsSaveImageV2 = false;
406
- }
407
- }
408
- var resourceId = this.transport.invoke('replay.saveImage', {
409
- path: stored.path,
410
- width: stored.width,
411
- height: stored.height,
445
+ });
412
446
  });
413
- if (!resourceId)
414
- return undefined;
415
- return __assign({ resourceId: resourceId,
416
- // V1 cannot report encoded size. A conservative frame-limit estimate
417
- // still prevents configured captureFps from multiplying traffic freely.
418
- byteSize: maxFrameBytes, width: stored.width, height: stored.height, byteSizeSource: 'frame_limit_estimate' }, (this.transport.platform === 'ios' ? { mimeType: 'image/png' } : {}));
447
+ };
448
+ FTSessionReplay.prototype.invokeSaveImage = function (method, payload) {
449
+ return this.transport.invokeAsync
450
+ ? this.transport.invokeAsync(method, payload)
451
+ : Promise.resolve(this.transport.invoke(method, payload));
419
452
  };
420
453
  FTSessionReplay.prototype.writePendingPointers = function (context, width, height) {
421
454
  var pointerEvents = this.scaledPendingPointers(width, height);