{"_id":"@cloudcare/cocos-session-replay","_rev":"2-958064c40a4798f2c0c6a441bc807b29","name":"@cloudcare/cocos-session-replay","dist-tags":{"latest":"0.1.0-alpha.7"},"versions":{"0.1.0-alpha.6":{"name":"@cloudcare/cocos-session-replay","version":"0.1.0-alpha.6","keywords":["guance","cocos-creator","session-replay"],"author":{"name":"Guance Cloud"},"license":"Apache-2.0","_id":"@cloudcare/cocos-session-replay@0.1.0-alpha.6","maintainers":[{"name":"dataflux","email":"dcl@jiagouyun.com"},{"name":"br4donzhang","email":"brandonfaustine@gmail.com"}],"homepage":"https://github.com/GuanceCloud/datakit-cocos#readme","bugs":{"url":"https://github.com/GuanceCloud/datakit-cocos/issues"},"dist":{"shasum":"5d99fdf9def3e82beb63c1ea0690b46165f3f8d3","tarball":"https://registry.npmjs.org/@cloudcare/cocos-session-replay/-/cocos-session-replay-0.1.0-alpha.6.tgz","fileCount":169,"integrity":"sha512-+jQ4niEgBKidpsWu4Y9P1pTpRcI01h1Jkgk53NjB+TCsxmUmAanm/tPo6xi7eKf87wtCGE8aeKXHQm8sqQCaNg==","signatures":[{"sig":"MEUCIARKbTSR8mh1ZlzlWK236BCUJqSO6Jt4FMiR65yAzsOQAiEA6sbWEFhPCbZj6uZsX+bRq2PZ44odReIAoD/3sKWklaM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":359047},"_from":"file:/Users/coral/Documents/Agent Workspace/ft-sdk-cocos/artifacts/npm-token-release/0.1.0-alpha.6/cloudcare-cocos-session-replay-0.1.0-alpha.6.tgz","engines":{"node":">=14"},"exports":{"./creator2":{"types":"./dist/creator2/creator2/index.d.ts","default":"./dist/creator2/creator2/index.js","require":"./dist/creator2/creator2/index.js"},"./creator3":{"types":"./dist/creator3/creator3/index.d.ts","import":"./dist/creator3/creator3/index.js","default":"./dist/creator3/creator3/index.js"},"./package.json":"./package.json"},"_npmUser":{"name":"br4donzhang","email":"brandonfaustine@gmail.com"},"cocosSdk":{"creator2":"2.4.5-2.4.15","creator3":"3.6.3-3.8.x"},"_resolved":"/Users/coral/Documents/Agent Workspace/ft-sdk-cocos/artifacts/npm-token-release/0.1.0-alpha.6/cloudcare-cocos-session-replay-0.1.0-alpha.6.tgz","_integrity":"sha512-+jQ4niEgBKidpsWu4Y9P1pTpRcI01h1Jkgk53NjB+TCsxmUmAanm/tPo6xi7eKf87wtCGE8aeKXHQm8sqQCaNg==","repository":{"url":"git+https://github.com/GuanceCloud/datakit-cocos.git","type":"git","directory":"packages/cocos-session-replay"},"_npmVersion":"11.17.0","description":"Optional Session Replay for the Guance Cocos Creator SDK","directories":{},"_nodeVersion":"26.4.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@cloudcare/cocos-sdk":"0.1.0-alpha.6"},"_npmOperationalInternal":{"tmp":"tmp/cocos-session-replay_0.1.0-alpha.6_1789199927652_0.7067169254868901","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-alpha.7":{"_id":"@cloudcare/cocos-session-replay@0.1.0-alpha.7","bugs":{"url":"https://github.com/GuanceCloud/datakit-cocos/issues"},"dist":{"shasum":"01e022a1ba0af28c43ed1fb9e28d625cea9fef0f","tarball":"https://registry.npmjs.org/@cloudcare/cocos-session-replay/-/cocos-session-replay-0.1.0-alpha.7.tgz","fileCount":161,"integrity":"sha512-aHv+fp4jwn7JgiZTVrz+prjG4UEwsKTZJEOS2MecDTmHo2j0VtWuTQsSal03NTwjpC7iB6OlbfkEwgCw2N0/IA==","signatures":[{"sig":"MEUCIQCRG0FRmdbNGg6mSI+WZCFQRBvVkHUbSXkxsB5C1j+5bgIgEp6MzRZfYLJoJ/r6sOJ2FbjmUqpXMeQZngTuTT2pghY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCID5s3CRGAxPEgzeY3+rwC0gN+yUpcppH/lxinaPnR1DXAiA6tIa4+VcNXOh1A0MHSv2/oKRFFYINIrS8hQ3f7xuZzQ=="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cloudcare%2fcocos-session-replay@0.1.0-alpha.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":368257},"name":"@cloudcare/cocos-session-replay","_from":"file:/home/runner/work/datakit-cocos/datakit-cocos/artifacts/npm-token-release/0.1.0-alpha.7/cloudcare-cocos-session-replay-0.1.0-alpha.7.tgz","author":{"name":"Guance Cloud"},"engines":{"node":">=14"},"exports":{"./creator2":{"types":"./dist/creator2/creator2/index.d.ts","default":"./dist/creator2/creator2/index.js","require":"./dist/creator2/creator2/index.js"},"./creator3":{"types":"./dist/creator3/creator3/index.d.ts","import":"./dist/creator3/creator3/index.js","default":"./dist/creator3/creator3/index.js"},"./package.json":"./package.json"},"license":"Apache-2.0","version":"0.1.0-alpha.7","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c2b9643f-3a1f-43b4-931b-2f0a1d8dc077"}},"cocosSdk":{"creator2":"2.4.5-2.4.15","creator3":"3.6.3-3.8.x"},"homepage":"https://github.com/GuanceCloud/datakit-cocos#readme","keywords":["guance","cocos-creator","session-replay"],"_resolved":"/home/runner/work/datakit-cocos/datakit-cocos/artifacts/npm-token-release/0.1.0-alpha.7/cloudcare-cocos-session-replay-0.1.0-alpha.7.tgz","_integrity":"sha512-aHv+fp4jwn7JgiZTVrz+prjG4UEwsKTZJEOS2MecDTmHo2j0VtWuTQsSal03NTwjpC7iB6OlbfkEwgCw2N0/IA==","repository":{"url":"git+https://github.com/GuanceCloud/datakit-cocos.git","type":"git","directory":"packages/cocos-session-replay"},"_npmVersion":"11.19.0","description":"Optional Session Replay for the Guance Cocos Creator SDK","directories":{},"maintainers":[{"name":"dataflux","email":"dcl@jiagouyun.com"},{"name":"br4donzhang","email":"brandonfaustine@gmail.com"}],"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@cloudcare/cocos-sdk":"0.1.0-alpha.7"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cocos-session-replay_0.1.0-alpha.7_1789388234449_0.3344470581511785"}}},"time":{"created":"2026-09-12T07:58:47.512Z","modified":"2026-09-14T12:17:14.945Z","0.1.0-alpha.6":"2026-09-12T07:58:47.795Z","0.1.0-alpha.7":"2026-09-14T12:17:14.543Z"},"bugs":{"url":"https://github.com/GuanceCloud/datakit-cocos/issues"},"author":{"name":"Guance Cloud"},"license":"Apache-2.0","homepage":"https://github.com/GuanceCloud/datakit-cocos#readme","keywords":["guance","cocos-creator","session-replay"],"repository":{"url":"git+https://github.com/GuanceCloud/datakit-cocos.git","type":"git","directory":"packages/cocos-session-replay"},"description":"Optional Session Replay for the Guance Cocos Creator SDK","maintainers":[{"name":"dataflux","email":"dcl@jiagouyun.com"},{"name":"br4donzhang","email":"brandonfaustine@gmail.com"}],"readme":"# Guance Cocos Session Replay\n\nOptional Session Replay for native Android and iOS applications built with Cocos Creator 2.4 and 3.x. Install the exact same version of `@cloudcare/cocos-sdk` and `@cloudcare/cocos-session-replay`.\n\n```sh\nnpm install @cloudcare/cocos-sdk@<version> @cloudcare/cocos-session-replay@<version>\nnpx guance-cocos install --replay\n```\n\nReopen Creator and rebuild the native project. Use `--creator 2` or `--creator 3` if automatic detection is unavailable. Add `--ios-dependency-manager spm` to select Swift Package Manager; CocoaPods remains the default.\n\n## Standalone application\n\n```ts\nimport { guanceSdk as baseSdk } from '@cloudcare/cocos-sdk/creator3';\nimport { withSessionReplay } from '@cloudcare/cocos-session-replay/creator3';\n\nexport const sdk = withSessionReplay(baseSdk);\nsdk.start({\n  sdk: { datakitUrl: 'http://localhost:9529' },\n  rum: { androidAppId: 'your-app-id', iosAppId: 'your-app-id' },\n  replay: { captureFps: 1, touchPrivacy: 'hide' },\n});\n```\n\nFor Creator 2, use the `/creator2` entry from both packages. Compose before starting or attaching the base SDK. `sdk.setReplayCamera(camera)` selects the capture camera; `sdk.replay.setPrivacy(node, 'mask')` protects a node. The installer places `ReplayPrivacy.ts` under `assets/guance-cocos-sdk` for scene/prefab use.\n\n## Hybrid application\n\nThe native host owns SDK/RUM/Replay initialization and sampling. Attach the composed SDK to that instance:\n\n```ts\nsdk.attach({ replay: { captureFps: 1 }, autoTrack: { scenes: true } });\nsdk.enterCocos();\n// When returning to the native host:\nsdk.leaveCocos();\n```\n\nIf automatic scene tracking is disabled, pass a `viewName` to `enterCocos`. Use `leaveCocos` instead of `shutdown` in Hybrid mode. Replay uses the native host's existing RUM session, image storage, and uploader.\n\n## Image size and traffic\n\nThe per-image behavior below is included in `0.1.0-alpha.7`. The device reference used locally packed development `0.1.0-alpha.6` packages containing commit `ef1137b`; published `0.1.0-alpha.6` packages predate this change.\n\nSet the capture frequency and per-image limits independently:\n\n```ts\nconst replay = {\n  captureFps: 3,\n  maxImageDimension: 720,\n  imagePolicy: { quality: 'medium' as const, maxFrameBytes: 40 * 1024 },\n};\nsdk.attach({ replay }); // Or pass replay to sdk.start in standalone mode.\n```\n\n`captureFps` accepts integers from 1 to 5 (default 1). `maxImageDimension` accepts 1–2048 and overrides the preset's longest edge. `imagePolicy.maxFrameBytes` accepts 1 KiB–1 MiB and overrides the preset's encoded size limit for **every image**, including new-view and rotation frames. The native encoder reduces quality, then dimensions if needed; a frame that still exceeds the limit is rejected while pending touches can continue to be written.\n\n| Preset | Longest edge | Initial encoding quality | Per-image limit | Full-rate image ceiling at 2 FPS (MiB/min) | Full-rate image ceiling at 3 FPS (MiB/min) |\n| --- | ---: | ---: | ---: | ---: | ---: |\n| `low` | 480 px | 0.35 | 20 KiB | 2.34 | 3.52 |\n| `medium` (default preset) | 720 px | 0.45 | 40 KiB | 4.69 | 7.03 |\n| `high` | 960 px | 0.60 | 80 KiB | 9.38 | 14.06 |\n\nThese are approximate theoretical image-only ceilings per recorded session at the configured frame rate, calculated as `maxFrameBytes × captureFps × 60 / 1048576`. They are **not measured typical traffic, a traffic range, or a rolling quota**. Configuration does not establish a useful lower bound: actual traffic depends on encoded image size, scene changes, and the number of accepted frames. Report typical ranges only from measurements of representative scenes at each configuration. A static scene may stop producing additional images after its first frame, but that does not make zero a representative minimum for an active recording. Replay segments, touch events, other telemetry, network overhead, and retries are excluded. Session sampling reduces aggregate traffic across users; it does not reduce the per-image limit in a recorded session.\n\n### Battle re-encoding sizing reference\n\nThe following **sample-based estimates** provide a numeric lower and upper reference for active gameplay. A local test re-encoded 21 existing 720×405 Battle WebP images with libwebp 1.6.0, using the Android policy's initial quality and size-reduction steps. All 21 images were accepted in each preset. The ranges multiply the smallest and largest encoded sample sizes by 120 or 180 images per minute; they do not discount static frames or missed captures.\n\n| Preset | Encoded sample size (bytes/image) | Estimated images at 2 FPS (MiB/min) | Estimated images at 3 FPS (MiB/min) |\n| --- | ---: | ---: | ---: |\n| `low` | 5,482–6,054 | 0.63–0.69 | 0.94–1.04 |\n| `medium` | 10,168–11,282 | 1.16–1.29 | 1.75–1.94 |\n| `high` | 10,776–12,100 | 1.23–1.38 | 1.85–2.08 |\n\nThis is a local re-encoding estimate using already-compressed images, **not a continuous 2/3 FPS device recording, an iOS JPEG measurement, or guaranteed bounds for other scenes**. Low was resized to 480×270; medium and high used the source 720×405 without upscaling, so the high row does not characterize a 960 px capture. Textures, particles, camera motion, alpha, and native encoder differences can change the range. Only image data is included; the separate full-rate ceilings above still describe the configured per-image limits.\n\n### Android device reference\n\nA September 13, 2026 Creator 2.4.9 Android Battle recording configured for 3 FPS, medium, 720 px and 40 KiB/image produced 83 available WebP images totaling 1,008,030 bytes over 28.516 seconds between its first and last image. Each image was 720×405, with an encoded size of 11,280–13,098 bytes (mean 12,144.94 bytes). Image traffic was **2.02 MiB/min**. The full view averaged 2.88 FPS, including an initial 1.017-second interval; the subsequent 81 intervals averaged **2.95 FPS**.\n\nAt a full 3 FPS, the measured smallest and largest Battle images imply **1.94–2.25 MiB/min**, with **2.08 MiB/min** at the mean size. This is a sample-based planning reference, not guaranteed bounds for other scenes. It is more representative of this Android Battle scene than the earlier medium re-encoding estimate of 1.75–1.94 MiB/min. The low/high rows above remain re-encoding estimates; no device measurements for those presets are claimed.\n\nFor measurements, use `unique image payload bytes / recorded seconds × 60 / 1048576`. Deduplicate repeated playback downloads by resource ID and use the duration of the same records whose bytes are counted. Across this recording, the raw record span was 68.953 seconds while the console session header showed 48.15 seconds; mixing those durations would distort the result. Two images outside Battle were unavailable from the server, so the whole-session download total is incomplete. The Battle images were all available.\n\nFor planning, use `average encoded bytes × expected saved images per minute / 1048576`; at a full rate the expected count is `captureFps × 60`. Add Replay segments, touch metadata, transport overhead and retries separately. Downloaded image payload is not a measurement of all device upload traffic. Session sampling scales aggregate recorded minutes, while error-session sampling adds further recordings; neither changes the size limit of an accepted image.\n\nThere is no rolling minute budget, budget-triggered throttling, or 100 KiB first-frame allowance. Remove the old `maxBytesPerMinute` and `adaptiveCapture` options; they are no longer part of the API, and extra legacy JavaScript properties do not enable a limit. Capture processing time is included in the target frame interval. Identical/approximately static frames, native encoding rejection, and device processing delays can still reduce actual output; missed time slots are skipped without concurrent image jobs.\n\nSupplying `imagePolicy` enables the native V2 image encoder (Android WebP, iOS JPEG) and its size limits, even when using `{}` to select the medium preset. Update the native Replay SDK and rebuild the native application. An unavailable V2 encoder produces an explicit error and does not fall back to unbounded storage. Omitting `imagePolicy` preserves legacy image storage: it still uses `captureFps` and `maxImageDimension`, but has **no encoded-byte limit**, and the table above does not apply. Legacy image bytes are reported as unavailable in diagnostics rather than estimated as the per-frame limit.\n\n## Migration from the combined package\n\nAdd this package and compose the existing SDK with `withSessionReplay`. Move the old `setReplayCamera(camera)` call to `sdk.setReplayCamera(camera)`. Import Replay configuration types from this package. Existing `start({ replay })`, `attach({ replay })`, and `sdk.replay` operations are available on the composed SDK.\n\nThe base package alone does not accept Replay configuration. Missing or incompatible native Replay integration reports an error when enabling Replay, with instructions to rerun installation and rebuild.\n\nRun `npx guance-cocos install --no-replay` and rebuild to remove SDK-managed native Replay integration. Existing ReplayPrivacy scripts and their `.meta` identifiers are preserved because scenes may reference them. Native Replay independently used by a Hybrid host must remain installed by that host.\n\n## Native dependencies\n\nThis package carries the optional Replay bridge, asynchronous image workers, C++ frame-file bindings, and privacy components. Its integration descriptor adds Android `ft-session-replay`, or iOS `GuanceSDK/FTSessionReplay` / `GuanceSessionReplay`. Base SDK dependencies are shared rather than duplicated.\n\nLicensed under Apache-2.0; see `LICENSE` and `THIRD_PARTY_NOTICES`.\n","readmeFilename":"README.md"}