@truewatchtech/cocos-sdk 0.1.0-alpha.4 → 0.1.0-alpha.7
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 +49 -1
- package/bin/cli.cjs +48 -18
- package/bin/legacy-asset-hashes.json +32 -0
- package/bin/managed-assets.cjs +67 -0
- package/dist/creator2/core/client.d.ts +55 -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/transport.d.ts +20 -0
- package/dist/creator2/core/transport.d.ts.map +1 -1
- package/dist/creator2/core/transport.js.map +1 -1
- 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 +55 -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/transport.d.ts +20 -0
- package/dist/creator3/core/transport.d.ts.map +1 -1
- package/dist/creator3/core/transport.js.map +1 -1
- 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 -24
- 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 +118 -28
- package/extensions/creator2/install-spm.cjs +198 -0
- package/extensions/creator2/legacy-asset-hashes.json +32 -0
- package/extensions/creator2/managed-assets.cjs +67 -0
- package/extensions/creator3/install-native.cjs +118 -28
- package/extensions/creator3/install-spm.cjs +198 -0
- package/extensions/creator3/legacy-asset-hashes.json +32 -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 +8 -203
- package/native/ios/FTCocosBridge.podspec +3 -4
- package/native/ios/Package.swift +25 -0
- package/native/ios/include/FTCocosBridge.h +2 -0
- 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
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## Introduction
|
|
9
9
|
|
|
10
|
-
TrueWatch Application Monitoring collects and analyzes RUM, Log,
|
|
10
|
+
TrueWatch Application Monitoring collects and analyzes RUM, Log, and Trace data from Cocos Creator applications. The SDK supports native Android and iOS builds for Cocos Creator 2.4 and 3.x.
|
|
11
11
|
|
|
12
12
|
## Supported Scope
|
|
13
13
|
|
|
@@ -18,6 +18,54 @@ TrueWatch Application Monitoring collects and analyzes RUM, Log, Trace, and Sess
|
|
|
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
|
+
## Optional Session Replay
|
|
22
|
+
|
|
23
|
+
Session Replay is distributed separately as `@truewatchtech/cocos-session-replay`.
|
|
24
|
+
Install both packages at the exact same version and run `npx truewatch-cocos install --replay`.
|
|
25
|
+
Compose the SDK with `withSessionReplay` from the matching `/creator2` or `/creator3` entry
|
|
26
|
+
before using Replay configuration. Camera selection moves to `sdk.setReplayCamera(camera)`.
|
|
27
|
+
|
|
28
|
+
Base-only applications continue using this package and its normal initialization API.
|
|
29
|
+
Run `npx truewatch-cocos install --no-replay` and rebuild to remove an existing SDK-managed
|
|
30
|
+
Replay native integration. Existing scene component scripts and metadata are preserved.
|
|
31
|
+
See the [Replay package guide](https://github.com/TrueWatchTech/datakit-cocos/tree/main/packages/cocos-session-replay).
|
|
32
|
+
|
|
33
|
+
## iOS dependency manager
|
|
34
|
+
|
|
35
|
+
CocoaPods remains the default. To use Swift Package Manager, add
|
|
36
|
+
`cocos-sdk.config.json` to your **Cocos project root** (beside `assets`):
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"ios": {
|
|
41
|
+
"dependencyManager": "spm"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Alternatively, save this setting when installing the extension:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
npx @truewatchtech/cocos-sdk install --ios-dependency-manager spm
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Rebuild the native iOS project in Creator after changing the configuration. The
|
|
53
|
+
extension links the local `FTCocosBridge` package and Xcode resolves the pinned
|
|
54
|
+
iOS SDK from Git. Fresh SPM projects do not require `pod install`; open the
|
|
55
|
+
`.xcodeproj`. If the host uses CocoaPods for other libraries, continue opening
|
|
56
|
+
its `.xcworkspace`.
|
|
57
|
+
|
|
58
|
+
When switching an existing installation, the extension removes its managed SDK
|
|
59
|
+
Pod entries and runs `pod install` if Pods were previously installed. Other Pods
|
|
60
|
+
are preserved. Manually declared SDK Pods or other Pods that depend on the same
|
|
61
|
+
native SDK must be migrated first to avoid duplicate linking. Set the value to
|
|
62
|
+
`cocoapods` to switch back, then run `pod install` as usual.
|
|
63
|
+
|
|
64
|
+
Creator 3 CMake regeneration restores the package integration automatically during
|
|
65
|
+
Xcode builds. If you regenerate the project by running CMake separately, rerun
|
|
66
|
+
Creator's native build integration before opening Xcode. Hybrid examples use the
|
|
67
|
+
same configuration with their existing `native:install` command.
|
|
68
|
+
|
|
21
69
|
## Examples
|
|
22
70
|
|
|
23
71
|
[TrueWatch SDK Cocos Creator Demo](https://github.com/TrueWatchTech/datakit-cocos/tree/main/examples)
|
package/bin/cli.cjs
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
|
+
const { createRequire } = require('module');
|
|
7
|
+
const { syncManagedDirectory } = require('./managed-assets.cjs');
|
|
6
8
|
|
|
7
9
|
const packageRoot = path.resolve(__dirname, '..');
|
|
8
10
|
const metadata = require(path.join(packageRoot, 'package.json'));
|
|
@@ -27,15 +29,51 @@ const creatorMajor = resolveCreatorMajor(projectRoot, readOption(rawArguments, '
|
|
|
27
29
|
const container = creatorMajor === 2 ? 'packages' : 'extensions';
|
|
28
30
|
const destination = path.join(projectRoot, container, 'truewatch-cocos-sdk');
|
|
29
31
|
const extensionSource = path.join(packageRoot, 'extensions', `creator${creatorMajor}`);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const manager = readOption(rawArguments, '--ios-dependency-manager');
|
|
33
|
+
if (manager !== undefined && !['spm', 'cocoapods'].includes(manager)) {
|
|
34
|
+
fail('Invalid --ios-dependency-manager. Expected spm or cocoapods.');
|
|
35
|
+
}
|
|
36
|
+
const configFile = path.join(projectRoot, 'cocos-sdk.config.json');
|
|
37
|
+
const config = readJson(configFile) || {};
|
|
38
|
+
if (rawArguments.includes('--replay') && rawArguments.includes('--no-replay')) fail('Choose either --replay or --no-replay.');
|
|
39
|
+
const replayEnabled = rawArguments.includes('--replay') ? true
|
|
40
|
+
: rawArguments.includes('--no-replay') ? false : config.replay?.enabled === true;
|
|
41
|
+
let replayRoot;
|
|
42
|
+
let replayDescriptor;
|
|
43
|
+
if (replayEnabled) {
|
|
44
|
+
try {
|
|
45
|
+
const projectRequire = createRequire(path.join(projectRoot, 'package.json'));
|
|
46
|
+
replayRoot = path.dirname(projectRequire.resolve('@truewatchtech/cocos-session-replay/package.json'));
|
|
47
|
+
} catch {
|
|
48
|
+
fail('Session Replay is not installed. Install @truewatchtech/cocos-session-replay at the same version as @truewatchtech/cocos-sdk, then rerun with --replay.');
|
|
49
|
+
}
|
|
50
|
+
const replayPackage = readJson(path.join(replayRoot, 'package.json'));
|
|
51
|
+
replayDescriptor = readJson(path.join(replayRoot, 'native-integration.json'));
|
|
52
|
+
if (replayPackage.version !== metadata.version || replayPackage.peerDependencies?.[metadata.name] !== metadata.version
|
|
53
|
+
|| replayDescriptor?.schemaVersion !== 1 || replayDescriptor?.version !== metadata.version || replayDescriptor?.baseVersion !== metadata.version) {
|
|
54
|
+
fail('Replay package and native integration must exactly match the base SDK version.');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const sources = [{ root: extensionSource }, { root: path.join(packageRoot, 'native'), prefix: 'native/' }];
|
|
58
|
+
if (replayRoot) sources.push({ root: path.join(replayRoot, 'native'), prefix: 'replay-native/' });
|
|
59
|
+
const generated = {
|
|
60
|
+
'sdk-integration.json': JSON.stringify({ schemaVersion: 1, version: metadata.version, replay: replayEnabled }, null, 2) + '\n',
|
|
61
|
+
};
|
|
62
|
+
if (replayDescriptor) generated['replay-integration.json'] = JSON.stringify(replayDescriptor, null, 2) + '\n';
|
|
63
|
+
syncManagedDirectory(destination, sources, generated);
|
|
33
64
|
const componentDestination = path.join(projectRoot, 'assets', 'truewatch-cocos-sdk');
|
|
34
|
-
|
|
35
|
-
|
|
65
|
+
if (replayRoot) syncManagedDirectory(componentDestination, [{ root: path.join(replayRoot, 'components', `creator${creatorMajor}`) }]);
|
|
66
|
+
// Keep existing component scripts and .meta files when disabling Replay: scenes may reference them.
|
|
67
|
+
if (manager !== undefined) config.ios = { ...config.ios, dependencyManager: manager };
|
|
68
|
+
if (rawArguments.includes('--replay') || rawArguments.includes('--no-replay') || config.replay) {
|
|
69
|
+
config.replay = { ...config.replay, enabled: replayEnabled };
|
|
70
|
+
}
|
|
71
|
+
if (manager !== undefined || rawArguments.includes('--replay') || rawArguments.includes('--no-replay')) {
|
|
72
|
+
fs.writeFileSync(configFile, `${JSON.stringify(config, null, 2)}\n`);
|
|
73
|
+
}
|
|
36
74
|
process.stdout.write(
|
|
37
|
-
`Installed ${metadata.name} for Cocos Creator ${creatorMajor} at ${destination}\n`
|
|
38
|
-
+ `Installed ReplayPrivacy at ${componentDestination}. Add it through Session Replay/ReplayPrivacy in the component menu.\n`
|
|
75
|
+
`Installed ${metadata.name} for Cocos Creator ${creatorMajor} at ${destination} (Replay: ${replayEnabled ? 'enabled' : 'disabled'})\n`
|
|
76
|
+
+ (replayEnabled ? `Installed ReplayPrivacy at ${componentDestination}. Add it through Session Replay/ReplayPrivacy in the component menu.\n` : '')
|
|
39
77
|
+ 'Re-open Cocos Creator, enable the truewatch-cocos-sdk extension, and rebuild the native project.\n',
|
|
40
78
|
);
|
|
41
79
|
for (const duplicate of findDuplicateExtensions(path.join(projectRoot, container), destination)) {
|
|
@@ -109,17 +147,6 @@ function readOption(argumentsList, name) {
|
|
|
109
147
|
return inline ? inline.slice(prefix.length) : undefined;
|
|
110
148
|
}
|
|
111
149
|
|
|
112
|
-
function copyDirectory(source, destinationPath) {
|
|
113
|
-
if (!fs.existsSync(source)) fail(`Missing package asset: ${source}`);
|
|
114
|
-
fs.mkdirSync(destinationPath, { recursive: true });
|
|
115
|
-
for (const entry of fs.readdirSync(source, { withFileTypes: true })) {
|
|
116
|
-
const from = path.join(source, entry.name);
|
|
117
|
-
const to = path.join(destinationPath, entry.name);
|
|
118
|
-
if (entry.isDirectory()) copyDirectory(from, to);
|
|
119
|
-
else fs.copyFileSync(from, to);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
150
|
function printHelp() {
|
|
124
151
|
process.stdout.write([
|
|
125
152
|
'Usage: npx @truewatchtech/cocos-sdk install [options]',
|
|
@@ -127,6 +154,9 @@ function printHelp() {
|
|
|
127
154
|
'Options:',
|
|
128
155
|
' --project <path> Cocos project root (defaults to the current directory)',
|
|
129
156
|
' --creator <2|3> Override automatic Cocos Creator version detection',
|
|
157
|
+
' --replay Include the separately installed Session Replay package',
|
|
158
|
+
' --no-replay Remove SDK-managed Replay native integration on rebuild',
|
|
159
|
+
' --ios-dependency-manager <spm|cocoapods> Save the iOS dependency manager in cocos-sdk.config.json',
|
|
130
160
|
' -h, --help Show this help',
|
|
131
161
|
'',
|
|
132
162
|
].join('\n'));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[
|
|
2
|
+
"058341971ed42ddfde76c28ce19fcc0bba5020fec1f7e1c613c7bda7d2df7677",
|
|
3
|
+
"11ee16e609096ccfe90b17f61d87ab65275a39df4bef6f8c29577e7395aa00f8",
|
|
4
|
+
"15338071a78f1505265cc8efbdc9628e9362f7a2c9fc00989d57461126f8f3f5",
|
|
5
|
+
"1a51af27d68cdf0bf3ce709c9cd60f9b8a2d7defd46d06896ce9a916e1dfc767",
|
|
6
|
+
"2caa0d3d542f5cca0b6b7f3aa2851c7e296b08fce286202a844b52920b1f6dc0",
|
|
7
|
+
"3189144de638b936e14d64ddbf9d4c95e95146ceecc357021473ca8adcc757d1",
|
|
8
|
+
"48ff77a12a7b9b59172f5470a642f23e4c61e9f7e10ee6d9d3f4f41377d696ac",
|
|
9
|
+
"4d2dcd924f1073b8a6fb94d342bee33a281f93c19302104be172e5de9981b3f0",
|
|
10
|
+
"51c71e12df61cfe7e75c3d97080e31a398fbea8719a3e964cec5dd332df1202c",
|
|
11
|
+
"54340b775f6ba897ade2df2d9fcfc39d17372e246e951d77dd166f00265815a8",
|
|
12
|
+
"5f33108f27f38836214f2c11badd7bb76ba9ec090f9d5b1490834a9257976939",
|
|
13
|
+
"71e6ade990a65d1bec51fec02c94bfe804e591d47df7ed9a271c981e9cf1d71c",
|
|
14
|
+
"83df7e51a5e4f76aab6310870c665fc80334808c64fb9c92fee46b466e1b58c3",
|
|
15
|
+
"85ad9622480d954c33a4f9442a391f6d3d9d617a2f1261e5ad769170c6e9cf12",
|
|
16
|
+
"86cf732195aad676898520192ac8aa878267877dc09f85fcf425279d8badc9b8",
|
|
17
|
+
"910792f383c25cd46ddc7d851080a687fa532a93d605fb709b7baff9bb2789cf",
|
|
18
|
+
"95bdc516c4e1b72833af3bec13b18e3c2ac6ae83de284c3f711e97765ed1b461",
|
|
19
|
+
"a748564f0bba03effbf4aa381308f60eedcb618cbd2a37e1c67cdbee596e9ceb",
|
|
20
|
+
"a8a57b5892e7a5063078d561fce790b44d900d2bb3869e43ed4c4de82f1f62ed",
|
|
21
|
+
"cd03df57f7861d19b0a8e0a97e8aff1fa08e5c26d4f43152743968245632535b",
|
|
22
|
+
"d26fb42c6bee416eaf29bc2ed8579edc7a28ca3d0e18433dcb8abea11fac9920",
|
|
23
|
+
"d2d171e4ef1777facdb6fe665105372ea2e6452028d4c32f5e2ccc74dacc8850",
|
|
24
|
+
"d538d9eebaf181687ebf8537fc6ce7c8fae59fa424daeb45c3f900a8e210ecfc",
|
|
25
|
+
"d6c2cefddabd773d471138aad619ee9f90d0f39f18053efa4d43d8771668e410",
|
|
26
|
+
"df0be5a293b5259b02438e2555832a114548fed03ecdde5b80bbc621c800998d",
|
|
27
|
+
"df8e3014e583d60922cd1b7f7f16964c433b260a7e1a7e6c285cb08ce2d9e7e4",
|
|
28
|
+
"e70ca2a537cec56f8424ff4d551c1e97af133938fc7ba863a3944859dcfd194d",
|
|
29
|
+
"f0211acbaaa312bd5a4478bba81fa98293c855692ceca69f141600ff991c5904",
|
|
30
|
+
"f09f9b35ddfb17a7c4e4439384afae93ded6ee0285e778ad013d320cfc880cab",
|
|
31
|
+
"fa88198c5434613ff5ab2d44dce6e7eb8b825085b5b498402810eb144cf81f96"
|
|
32
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { createHash } = require('crypto');
|
|
5
|
+
const legacyHashes = new Set(require('./legacy-asset-hashes.json'));
|
|
6
|
+
// Older combined installations predate the ownership manifest. Never leave a
|
|
7
|
+
// locally modified obsolete Replay bridge compiling beside the new bridge.
|
|
8
|
+
const legacyReplayNames = new Set(['FTCocosReplayImageJobs.java', 'FTCocosReplayImageJobs.h', 'FTCocosReplayImageJobs.m', 'FTReplayFileBridge.h', 'FTReplayFileWorker.h']);
|
|
9
|
+
const manifestName = '.cocos-sdk-managed.json';
|
|
10
|
+
const hash = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
11
|
+
|
|
12
|
+
function files(root) {
|
|
13
|
+
const result = [];
|
|
14
|
+
if (!fs.existsSync(root)) return result;
|
|
15
|
+
function visit(directory) {
|
|
16
|
+
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
17
|
+
if (entry.name === manifestName || entry.name === '.DS_Store') continue;
|
|
18
|
+
const file = path.join(directory, entry.name);
|
|
19
|
+
if (entry.isSymbolicLink()) throw new Error(`[cocos-sdk] Refusing to copy symbolic link: ${file}`);
|
|
20
|
+
if (entry.isDirectory()) visit(file);
|
|
21
|
+
else result.push(path.relative(root, file).split(path.sep).join('/'));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
visit(root);
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Reconciles only files written by the SDK, preserving unrelated project assets. */
|
|
29
|
+
function syncManagedDirectory(destination, sources, overrides = {}) {
|
|
30
|
+
const desired = new Map();
|
|
31
|
+
for (const { root, prefix = '' } of sources) {
|
|
32
|
+
if (!fs.existsSync(root)) throw new Error(`[cocos-sdk] Missing package assets: ${root}`);
|
|
33
|
+
for (const file of files(root)) desired.set(prefix + file, fs.readFileSync(path.join(root, file)));
|
|
34
|
+
}
|
|
35
|
+
for (const [file, content] of Object.entries(overrides)) desired.set(file, Buffer.from(content));
|
|
36
|
+
const manifest = path.join(destination, manifestName);
|
|
37
|
+
const previous = fs.existsSync(manifest) ? JSON.parse(fs.readFileSync(manifest, 'utf8')) : {};
|
|
38
|
+
const existing = files(destination);
|
|
39
|
+
const remove = [];
|
|
40
|
+
// Check every conflict before writing or deleting any managed file.
|
|
41
|
+
for (const file of existing) {
|
|
42
|
+
const digest = hash(fs.readFileSync(path.join(destination, file)));
|
|
43
|
+
const old = previous[file];
|
|
44
|
+
const next = desired.get(file);
|
|
45
|
+
const legacy = legacyHashes.has(digest);
|
|
46
|
+
if (!next && !old && !legacy && legacyReplayNames.has(path.basename(file))) {
|
|
47
|
+
throw new Error(`[cocos-sdk] Preserve or reconcile modified legacy Replay asset before reinstalling: ${path.join(destination, file)}`);
|
|
48
|
+
}
|
|
49
|
+
if ((old || next) && digest !== old && !legacy && (!next || digest !== hash(next))) {
|
|
50
|
+
throw new Error(`[cocos-sdk] Preserve or reconcile modified SDK asset before reinstalling: ${path.join(destination, file)}`);
|
|
51
|
+
}
|
|
52
|
+
if (!next && (old || legacy) && !file.endsWith('.meta')) remove.push(file);
|
|
53
|
+
}
|
|
54
|
+
fs.mkdirSync(destination, { recursive: true });
|
|
55
|
+
for (const file of remove) fs.unlinkSync(path.join(destination, file));
|
|
56
|
+
const nextManifest = {};
|
|
57
|
+
for (const [file, content] of desired) {
|
|
58
|
+
const target = path.resolve(destination, file);
|
|
59
|
+
if (!target.startsWith(path.resolve(destination) + path.sep)) throw new Error('Invalid SDK asset path');
|
|
60
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
61
|
+
if (!fs.existsSync(target) || hash(fs.readFileSync(target)) !== hash(content)) fs.writeFileSync(target, content);
|
|
62
|
+
nextManifest[file] = hash(content);
|
|
63
|
+
}
|
|
64
|
+
fs.writeFileSync(manifest, `${JSON.stringify(nextManifest, null, 2)}\n`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = { syncManagedDirectory };
|
|
@@ -1,11 +1,55 @@
|
|
|
1
1
|
import { FTLogger, FTMobileAgent, FTRUM, FTTrace } from './modules.js';
|
|
2
|
-
import { FTSessionReplay, type FTCanvasCapture, type FTReplayPointerSource } from './replay.js';
|
|
3
2
|
import type { FTNativeTransport } from './transport.js';
|
|
4
3
|
import type { FTAutoTrackingConfig, FTCocosConfig, FTCocosEnterOptions, FTCocosHybridConfig } from './types.js';
|
|
5
4
|
export interface FTAutoTrackingController {
|
|
6
5
|
start(config: FTAutoTrackingConfig, viewName?: string): void;
|
|
7
6
|
stop(): void;
|
|
8
7
|
}
|
|
8
|
+
export interface FTSDKLifecycle {
|
|
9
|
+
/**
|
|
10
|
+
* Validates or prepares the extension before standalone native SDK initialization.
|
|
11
|
+
* Throwing aborts startup before the base SDK is initialized.
|
|
12
|
+
*/
|
|
13
|
+
beforeStart?(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Starts the extension after the base SDK and configured modules initialize,
|
|
16
|
+
* but before Cocos automatic tracking starts. If this hook throws, the native
|
|
17
|
+
* SDK remains initialized; startup is not automatically rolled back.
|
|
18
|
+
*/
|
|
19
|
+
afterStart?(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Prepares the extension before the native Hybrid attachment call.
|
|
22
|
+
* The native host already owns SDK initialization at this point.
|
|
23
|
+
*/
|
|
24
|
+
beforeAttach?(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Undoes extension preparation if beforeAttach or the native attachment call
|
|
27
|
+
* fails. Must tolerate partial preparation; errors from this hook are ignored
|
|
28
|
+
* so the original attachment error can be rethrown.
|
|
29
|
+
*/
|
|
30
|
+
rollbackAttach?(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Starts extension activity when entering Cocos in Hybrid mode, before Cocos
|
|
33
|
+
* automatic tracking starts. A failure triggers the leave hook for cleanup.
|
|
34
|
+
*/
|
|
35
|
+
enter?(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Stops extension activity when leaving Cocos in Hybrid mode, after automatic
|
|
38
|
+
* tracking cleanup is attempted. Also runs if entering Cocos fails, so it must
|
|
39
|
+
* tolerate partial startup. The native host SDK must remain running.
|
|
40
|
+
*/
|
|
41
|
+
leave?(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Releases standalone extension resources after automatic tracking cleanup is
|
|
44
|
+
* attempted and before the base native SDK shuts down. Base SDK shutdown is
|
|
45
|
+
* still attempted if this hook throws. Not called for Hybrid applications.
|
|
46
|
+
*/
|
|
47
|
+
shutdown?(): void;
|
|
48
|
+
}
|
|
49
|
+
export interface FTSDKExtension<T> {
|
|
50
|
+
value: T;
|
|
51
|
+
lifecycle: FTSDKLifecycle;
|
|
52
|
+
}
|
|
9
53
|
/**
|
|
10
54
|
* Cocos SDK facade exposed through the platform entry point's SDK
|
|
11
55
|
* singleton. Do not construct this class directly.
|
|
@@ -13,6 +57,7 @@ export interface FTAutoTrackingController {
|
|
|
13
57
|
export declare class FTCocosSDK {
|
|
14
58
|
private readonly transport;
|
|
15
59
|
private readonly autoTracking?;
|
|
60
|
+
readonly engine: 'creator2' | 'creator3';
|
|
16
61
|
/** Base SDK lifecycle and user-binding operations. */
|
|
17
62
|
readonly mobile: FTMobileAgent;
|
|
18
63
|
/** Real User Monitoring operations. */
|
|
@@ -21,12 +66,15 @@ export declare class FTCocosSDK {
|
|
|
21
66
|
readonly logger: FTLogger;
|
|
22
67
|
/** Distributed-tracing operations. */
|
|
23
68
|
readonly trace: FTTrace;
|
|
24
|
-
|
|
25
|
-
|
|
69
|
+
readonly extensionProtocol = 1;
|
|
70
|
+
private extension;
|
|
71
|
+
private extensionId;
|
|
26
72
|
private state;
|
|
27
73
|
private hybridAutoTracking;
|
|
28
74
|
private readonly ownership;
|
|
29
|
-
constructor(transport: FTNativeTransport,
|
|
75
|
+
constructor(transport: FTNativeTransport, autoTracking?: FTAutoTrackingController | undefined, engine?: 'creator2' | 'creator3');
|
|
76
|
+
/** Attaches an optional package before SDK initialization. */
|
|
77
|
+
registerExtension<T>(id: string, version: string, engine: string, factory: () => FTSDKExtension<T>): T;
|
|
30
78
|
/**
|
|
31
79
|
* Initializes the native SDK and the configured modules for a standalone
|
|
32
80
|
* Cocos application.
|
|
@@ -46,12 +94,12 @@ export declare class FTCocosSDK {
|
|
|
46
94
|
* Call this once before the first {@link enterCocos}. This method does not
|
|
47
95
|
* initialize or shut down the native SDK.
|
|
48
96
|
*
|
|
49
|
-
* @param config - Cocos tracking
|
|
97
|
+
* @param config - Cocos tracking settings for the SDK owned by the native host.
|
|
50
98
|
* @throws If standalone initialization has already started.
|
|
51
99
|
*/
|
|
52
100
|
attach(config?: FTCocosHybridConfig): void;
|
|
53
101
|
/**
|
|
54
|
-
* Starts Cocos automatic tracking and
|
|
102
|
+
* Starts Cocos automatic tracking and registered extensions in Hybrid mode.
|
|
55
103
|
*
|
|
56
104
|
* @param options - Options for the Cocos view being entered.
|
|
57
105
|
* @throws If {@link attach} has not been called, or if `viewName` is omitted
|
|
@@ -59,7 +107,7 @@ export declare class FTCocosSDK {
|
|
|
59
107
|
*/
|
|
60
108
|
enterCocos(options?: FTCocosEnterOptions): void;
|
|
61
109
|
/**
|
|
62
|
-
* Stops Cocos automatic tracking and
|
|
110
|
+
* Stops Cocos automatic tracking and registered extensions in Hybrid mode.
|
|
63
111
|
* The native host SDK remains running.
|
|
64
112
|
*/
|
|
65
113
|
leaveCocos(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAkB,OAAO,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAkB,OAAO,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,MAAM,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7D,IAAI,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,IAAI,IAAI,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,IAAI,IAAI,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,IAAI,IAAI,CAAC;IACtB;;;;OAIG;IACH,cAAc,CAAC,IAAI,IAAI,CAAC;IACxB;;;OAGG;IACH,KAAK,CAAC,IAAI,IAAI,CAAC;IACf;;;;OAIG;IACH,KAAK,CAAC,IAAI,IAAI,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,IAAI,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,cAAc,CAAC;CAC3B;AAID;;;GAGG;AACH,qBAAa,UAAU;IAkBnB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU;IAnB1C,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,iBAAiB,KAAK;IAC/B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,WAAW,CAAqB;IAExC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;gBAG/B,SAAS,EAAE,iBAAiB,EAC5B,YAAY,CAAC,EAAE,wBAAwB,YAAA,EAC/C,MAAM,GAAE,UAAU,GAAG,UAAuB;IAQvD,8DAA8D;IAC9D,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;IAetG;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAiBlC;;;;;;;;;OASG;IACH,MAAM,CAAC,MAAM,GAAE,mBAAwB,GAAG,IAAI;IAsB9C;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,GAAE,mBAAwB,GAAG,IAAI;IA6BnD;;;OAGG;IACH,UAAU,IAAI,IAAI;IAclB;;;;;OAKG;IACH,QAAQ,IAAI,IAAI;CAcjB"}
|
|
@@ -13,16 +13,18 @@ var __assign = (this && this.__assign) || function () {
|
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.FTCocosSDK = void 0;
|
|
15
15
|
var modules_js_1 = require("./modules.js");
|
|
16
|
-
var replay_js_1 = require("./replay.js");
|
|
17
16
|
var version_js_1 = require("./version.js");
|
|
18
17
|
/**
|
|
19
18
|
* Cocos SDK facade exposed through the platform entry point's SDK
|
|
20
19
|
* singleton. Do not construct this class directly.
|
|
21
20
|
*/
|
|
22
21
|
var FTCocosSDK = /** @class */ (function () {
|
|
23
|
-
function FTCocosSDK(transport,
|
|
22
|
+
function FTCocosSDK(transport, autoTracking, engine) {
|
|
23
|
+
if (engine === void 0) { engine = 'creator3'; }
|
|
24
24
|
this.transport = transport;
|
|
25
25
|
this.autoTracking = autoTracking;
|
|
26
|
+
this.engine = engine;
|
|
27
|
+
this.extensionProtocol = 1;
|
|
26
28
|
this.state = 'idle';
|
|
27
29
|
this.hybridAutoTracking = {};
|
|
28
30
|
this.ownership = new modules_js_1.FTSDKOwnership();
|
|
@@ -30,8 +32,24 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
30
32
|
this.rum = new modules_js_1.FTRUM(transport, this.ownership);
|
|
31
33
|
this.logger = new modules_js_1.FTLogger(transport, this.ownership);
|
|
32
34
|
this.trace = new modules_js_1.FTTrace(transport, this.ownership);
|
|
33
|
-
this.replay = new replay_js_1.FTSessionReplay(transport, capture, pointerSource);
|
|
34
35
|
}
|
|
36
|
+
/** Attaches an optional package before SDK initialization. */
|
|
37
|
+
FTCocosSDK.prototype.registerExtension = function (id, version, engine, factory) {
|
|
38
|
+
if (version !== version_js_1.FT_COCOS_SDK_VERSION || engine !== this.engine) {
|
|
39
|
+
throw new Error('SDK extension version or Creator engine does not match the base SDK');
|
|
40
|
+
}
|
|
41
|
+
if (this.extension) {
|
|
42
|
+
if (id !== this.extensionId)
|
|
43
|
+
throw new Error('A different SDK extension is already installed');
|
|
44
|
+
return this.extension.value;
|
|
45
|
+
}
|
|
46
|
+
if (this.state !== 'idle')
|
|
47
|
+
throw new Error('Install SDK extensions before start() or attach()');
|
|
48
|
+
var extension = factory();
|
|
49
|
+
this.extension = extension;
|
|
50
|
+
this.extensionId = id;
|
|
51
|
+
return extension.value;
|
|
52
|
+
};
|
|
35
53
|
/**
|
|
36
54
|
* Initializes the native SDK and the configured modules for a standalone
|
|
37
55
|
* Cocos application.
|
|
@@ -44,10 +62,12 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
44
62
|
* @throws If the SDK is already started or attached.
|
|
45
63
|
*/
|
|
46
64
|
FTCocosSDK.prototype.start = function (config) {
|
|
47
|
-
var _a;
|
|
65
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
66
|
+
rejectReplayConfig(config);
|
|
48
67
|
if (this.state !== 'idle') {
|
|
49
68
|
throw new Error('start() and attach() are mutually exclusive');
|
|
50
69
|
}
|
|
70
|
+
(_c = (_a = this.extension) === null || _a === void 0 ? void 0 : (_b = _a.lifecycle).beforeStart) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
51
71
|
this.mobile.start(config.sdk);
|
|
52
72
|
// Base SDK installation already belongs to this Cocos runtime after the
|
|
53
73
|
// first bridge call succeeds, even if a later optional module fails.
|
|
@@ -58,10 +78,9 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
58
78
|
this.logger.start(config.logger);
|
|
59
79
|
if (config.trace)
|
|
60
80
|
this.trace.start(config.trace);
|
|
61
|
-
|
|
62
|
-
this.replay.start(config.replay);
|
|
81
|
+
(_f = (_d = this.extension) === null || _d === void 0 ? void 0 : (_e = _d.lifecycle).afterStart) === null || _f === void 0 ? void 0 : _f.call(_e);
|
|
63
82
|
if (config.autoTrack)
|
|
64
|
-
(
|
|
83
|
+
(_g = this.autoTracking) === null || _g === void 0 ? void 0 : _g.start(config.autoTrack);
|
|
65
84
|
};
|
|
66
85
|
/**
|
|
67
86
|
* Attaches Cocos instrumentation to an SDK instance initialized by the
|
|
@@ -70,11 +89,13 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
70
89
|
* Call this once before the first {@link enterCocos}. This method does not
|
|
71
90
|
* initialize or shut down the native SDK.
|
|
72
91
|
*
|
|
73
|
-
* @param config - Cocos tracking
|
|
92
|
+
* @param config - Cocos tracking settings for the SDK owned by the native host.
|
|
74
93
|
* @throws If standalone initialization has already started.
|
|
75
94
|
*/
|
|
76
95
|
FTCocosSDK.prototype.attach = function (config) {
|
|
96
|
+
var _a, _b, _c, _d, _e, _f;
|
|
77
97
|
if (config === void 0) { config = {}; }
|
|
98
|
+
rejectReplayConfig(config);
|
|
78
99
|
if (this.state === 'standalone') {
|
|
79
100
|
throw new Error('start() and attach() are mutually exclusive');
|
|
80
101
|
}
|
|
@@ -82,14 +103,16 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
82
103
|
return;
|
|
83
104
|
this.ownership.claimNativeHost();
|
|
84
105
|
try {
|
|
85
|
-
this.
|
|
106
|
+
(_c = (_a = this.extension) === null || _a === void 0 ? void 0 : (_b = _a.lifecycle).beforeAttach) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
86
107
|
this.transport.invoke('hybrid.attach', {
|
|
87
|
-
requiresReplay: config.replay !== undefined,
|
|
88
108
|
sdkVersion: version_js_1.FT_COCOS_SDK_VERSION,
|
|
89
109
|
});
|
|
90
110
|
}
|
|
91
111
|
catch (error) {
|
|
92
|
-
|
|
112
|
+
try {
|
|
113
|
+
(_f = (_d = this.extension) === null || _d === void 0 ? void 0 : (_e = _d.lifecycle).rollbackAttach) === null || _f === void 0 ? void 0 : _f.call(_e);
|
|
114
|
+
}
|
|
115
|
+
catch ( /* Preserve attachment error. */_g) { /* Preserve attachment error. */ }
|
|
93
116
|
this.ownership.releaseNativeHost();
|
|
94
117
|
throw error;
|
|
95
118
|
}
|
|
@@ -97,14 +120,14 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
97
120
|
this.state = 'hybrid-attached';
|
|
98
121
|
};
|
|
99
122
|
/**
|
|
100
|
-
* Starts Cocos automatic tracking and
|
|
123
|
+
* Starts Cocos automatic tracking and registered extensions in Hybrid mode.
|
|
101
124
|
*
|
|
102
125
|
* @param options - Options for the Cocos view being entered.
|
|
103
126
|
* @throws If {@link attach} has not been called, or if `viewName` is omitted
|
|
104
127
|
* while automatic scene tracking is disabled.
|
|
105
128
|
*/
|
|
106
129
|
FTCocosSDK.prototype.enterCocos = function (options) {
|
|
107
|
-
var _a, _b;
|
|
130
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
108
131
|
if (options === void 0) { options = {}; }
|
|
109
132
|
if (this.state === 'standalone') {
|
|
110
133
|
throw new Error('enterCocos() is only available after attach()');
|
|
@@ -119,35 +142,42 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
119
142
|
throw new TypeError('enterCocos.viewName is required when scene tracking is disabled');
|
|
120
143
|
}
|
|
121
144
|
try {
|
|
122
|
-
this.
|
|
123
|
-
(
|
|
145
|
+
(_c = (_a = this.extension) === null || _a === void 0 ? void 0 : (_b = _a.lifecycle).enter) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
146
|
+
(_d = this.autoTracking) === null || _d === void 0 ? void 0 : _d.start(this.hybridAutoTracking, viewName);
|
|
124
147
|
this.state = 'hybrid-entered';
|
|
125
148
|
}
|
|
126
149
|
catch (error) {
|
|
127
|
-
(_b = this.autoTracking) === null || _b === void 0 ? void 0 : _b.stop();
|
|
128
150
|
try {
|
|
129
|
-
this.
|
|
151
|
+
(_e = this.autoTracking) === null || _e === void 0 ? void 0 : _e.stop();
|
|
130
152
|
}
|
|
131
|
-
catch (
|
|
153
|
+
catch ( /* Preserve the entry error. */_j) { /* Preserve the entry error. */ }
|
|
154
|
+
try {
|
|
155
|
+
(_h = (_f = this.extension) === null || _f === void 0 ? void 0 : (_g = _f.lifecycle).leave) === null || _h === void 0 ? void 0 : _h.call(_g);
|
|
156
|
+
}
|
|
157
|
+
catch (_k) {
|
|
132
158
|
// Preserve the error that prevented entering Cocos.
|
|
133
159
|
}
|
|
134
160
|
throw error;
|
|
135
161
|
}
|
|
136
162
|
};
|
|
137
163
|
/**
|
|
138
|
-
* Stops Cocos automatic tracking and
|
|
164
|
+
* Stops Cocos automatic tracking and registered extensions in Hybrid mode.
|
|
139
165
|
* The native host SDK remains running.
|
|
140
166
|
*/
|
|
141
167
|
FTCocosSDK.prototype.leaveCocos = function () {
|
|
142
|
-
var _a;
|
|
168
|
+
var _a, _b, _c, _d;
|
|
143
169
|
if (this.state === 'standalone') {
|
|
144
170
|
throw new Error('leaveCocos() is only available after attach()');
|
|
145
171
|
}
|
|
146
172
|
if (this.state === 'idle' || this.state === 'hybrid-attached')
|
|
147
173
|
return;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
174
|
+
try {
|
|
175
|
+
(_a = this.autoTracking) === null || _a === void 0 ? void 0 : _a.stop();
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
(_d = (_b = this.extension) === null || _b === void 0 ? void 0 : (_c = _b.lifecycle).leave) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
179
|
+
this.state = 'hybrid-attached';
|
|
180
|
+
}
|
|
151
181
|
};
|
|
152
182
|
/**
|
|
153
183
|
* Stops a standalone SDK instance and releases its Cocos instrumentation.
|
|
@@ -156,16 +186,27 @@ var FTCocosSDK = /** @class */ (function () {
|
|
|
156
186
|
* native host owns SDK shutdown.
|
|
157
187
|
*/
|
|
158
188
|
FTCocosSDK.prototype.shutdown = function () {
|
|
159
|
-
var
|
|
189
|
+
var _this = this;
|
|
160
190
|
if (this.state === 'hybrid-attached' || this.state === 'hybrid-entered') {
|
|
161
191
|
throw new Error('The native host owns the native SDK; call leaveCocos() instead of shutdown()');
|
|
162
192
|
}
|
|
163
193
|
if (this.state === 'idle')
|
|
164
194
|
return;
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
195
|
+
var failure;
|
|
196
|
+
var cleanup = function (operation) {
|
|
197
|
+
try {
|
|
198
|
+
operation();
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (failure === undefined)
|
|
202
|
+
failure = error;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
cleanup(function () { var _a; return (_a = _this.autoTracking) === null || _a === void 0 ? void 0 : _a.stop(); });
|
|
206
|
+
cleanup(function () { var _a, _b, _c; return (_c = (_a = _this.extension) === null || _a === void 0 ? void 0 : (_b = _a.lifecycle).shutdown) === null || _c === void 0 ? void 0 : _c.call(_b); });
|
|
207
|
+
cleanup(function () { _this.mobile.shutdown(); _this.state = 'idle'; });
|
|
208
|
+
if (failure !== undefined)
|
|
209
|
+
throw failure;
|
|
169
210
|
};
|
|
170
211
|
return FTCocosSDK;
|
|
171
212
|
}());
|
|
@@ -173,4 +214,9 @@ exports.FTCocosSDK = FTCocosSDK;
|
|
|
173
214
|
function nonEmptyText(value) {
|
|
174
215
|
return typeof value === 'string' && value.trim().length > 0 ? value : undefined;
|
|
175
216
|
}
|
|
217
|
+
function rejectReplayConfig(config) {
|
|
218
|
+
if ('replay' in config) {
|
|
219
|
+
throw new Error('Session Replay requires @truewatchtech/cocos-session-replay. Install the package and use withSessionReplay() before passing replay configuration.');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
176
222
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../../src/core/client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,2CAAuF;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../../src/core/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type { FTAttributes, FTAutoTrackingConfig, FTCocosConfig, FTCocosEnterOptions, FTCocosHybridConfig, FTEnvironment,
|
|
1
|
+
export type { FTAttributes, FTAutoTrackingConfig, FTCocosConfig, FTCocosEnterOptions, FTCocosHybridConfig, FTEnvironment, FTLoggerConfig, FTLogLevel, FTPrimitive, FTResourceContent, FTResourceMetrics, FTRUMConfig, FTSDKConfig, FTTraceConfig, FTTraceType, FTUserData, FTValue, } from './types.js';
|
|
2
2
|
export { FT_COCOS_SDK_VERSION } from './version.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,aAAa,EACb,WAAW,EACX,UAAU,EACV,OAAO,GACR,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/index.ts"],"names":[],"mappings":";;;AAoBA,2CAAoD;AAA3C,kHAAA,oBAAoB,OAAA"}
|