@jam.dev/recording-links 0.3.0-electron.5 → 0.3.1
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/lib/electron.d.ts +8 -4
- package/lib/electron.js +1 -1
- package/lib/sdk.d.ts +6 -2
- package/lib/sdk.js +1 -1
- package/package.json +1 -1
package/lib/electron.d.ts
CHANGED
|
@@ -145,7 +145,7 @@ export declare function initialize(config: {
|
|
|
145
145
|
* jam.openRecorder('abc123');
|
|
146
146
|
*
|
|
147
147
|
* // Open with title
|
|
148
|
-
* jam.openRecorder({ recordingId: 'abc123',
|
|
148
|
+
* jam.openRecorder({ recordingId: 'abc123', jamTitle: 'Bug Report' });
|
|
149
149
|
*
|
|
150
150
|
* // Open with URLSearchParams (from protocol handler)
|
|
151
151
|
* const params = new URLSearchParams('jam-recording=abc123&jam-title=Bug+Report');
|
|
@@ -165,7 +165,9 @@ export interface IJamData {
|
|
|
165
165
|
/** Jam recording ID */
|
|
166
166
|
readonly recordingId: string;
|
|
167
167
|
/** Optional recording title */
|
|
168
|
-
readonly
|
|
168
|
+
readonly jamTitle: string | undefined | null;
|
|
169
|
+
/** Optional recording state JWT */
|
|
170
|
+
readonly state: string | undefined | null;
|
|
169
171
|
/**
|
|
170
172
|
* URLSearchParams containing jam-* query parameters.
|
|
171
173
|
* Follows the same convention as URL.searchParams.
|
|
@@ -179,12 +181,14 @@ export interface IJamData {
|
|
|
179
181
|
}
|
|
180
182
|
declare class JamData implements IJamData {
|
|
181
183
|
readonly recordingId: string;
|
|
182
|
-
readonly
|
|
184
|
+
readonly jamTitle: string | undefined | null;
|
|
185
|
+
readonly state: string | undefined | null;
|
|
183
186
|
get searchParams(): URLSearchParams;
|
|
184
187
|
get search(): string;
|
|
185
188
|
constructor(init: URLSearchParams | {
|
|
186
189
|
recordingId: string;
|
|
187
|
-
|
|
190
|
+
jamTitle?: string | null;
|
|
191
|
+
state?: string | null;
|
|
188
192
|
});
|
|
189
193
|
}
|
|
190
194
|
export declare function isJamRecorder(win: BrowserWindow | null): boolean;
|
package/lib/electron.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{app as e,session as
|
|
1
|
+
import{app as e,session as t,webContents as r,BrowserWindow as n,desktopCapturer as o}from"electron";const s={defaultSession:null,windows:new Map,openRecorderWindow(){throw new Error("Not initialized")},loadRecorderPage(){throw new Error("Not initialized")}},i=(e,t)=>{const s=e.frame,i=s?r.fromFrame(s):null,a=i?n.fromWebContents(i):null;u(a)?o.getSources({types:["screen","window"]}).then(e=>f(e,t,a)).catch(e=>{t({})}):t({})};async function a(r){if(!e.isReady())return e.whenReady().then(()=>a(r));const{defaultSession:n=t.defaultSession,defaultDisplayMediaRequestHandler:o=i}=r;s.defaultSession=n,s.openRecorderWindow=r.openRecorderWindow,s.loadRecorderPage=r.loadRecorderPage,o&&n.setDisplayMediaRequestHandler(o,{useSystemPicker:!0})}function d(e,t){const r=t??s.defaultSession;if(null===r)throw new Error("Cannot open recorder: no `session` found or provided");let n=s.windows.get(r);n||(n=s.openRecorderWindow(r),s.windows.set(r,n),n.on("closed",()=>s.windows.delete(r)));const o="string"==typeof e?new l({recordingId:e}):e instanceof l?e:new l(e);return s.loadRecorderPage(n,o).catch(e=>{}),n.isMinimized()&&n.restore(),n.focus(),n}function c(e,t){const r="string"==typeof e?new URL(e):e,n=new URLSearchParams;for(const[e,t]of r.searchParams.entries())e.startsWith("jam-")&&(n.set(e,t),r.searchParams.delete(e));return[r.href,n.has("jam-recording")?d(new l(n),t):null]}class l{get searchParams(){const e=new URLSearchParams;return e.set("jam-recording",this.recordingId),this.jamTitle&&e.set("jam-title",this.jamTitle),this.state&&e.set("jam-state",this.state),e}get search(){const e=this.searchParams.toString();return e?`?${e}`:""}constructor(e){if(e instanceof URLSearchParams){const t=e.get("jam-recording");if(!t)throw new Error("Missing jam-recording parameter");this.recordingId=t,this.jamTitle=e.get("jam-title"),this.state=e.get("jam-state")}else this.recordingId=e.recordingId,this.jamTitle=e.jamTitle||null,this.state=e.state||null}}function u(e){for(const t of s.windows.values())if(t===e)return!0;return!1}function f(e,t,r){const n=r?.getMediaSourceId(),o=e.filter(e=>!e.name.includes("DevTools")&&e.id!==n),s=o.find(e=>e.id.startsWith("window:")),i=o.find(e=>e.id.startsWith("screen:")),a=s||i||o[0];t(a?{video:a,audio:"loopback"}:{})}export{f as handleDisplayMediaRequest,a as initialize,u as isJamRecorder,d as openRecorder,c as openUrl};//# sourceMappingURL=electron.js.map
|
package/lib/sdk.d.ts
CHANGED
|
@@ -23,12 +23,14 @@ type RecorderSingleton = {
|
|
|
23
23
|
* @param recordingId - The ID of the recording to open
|
|
24
24
|
* @param params - Optional parameters for opening the recorder
|
|
25
25
|
* @param params.jamTitle - Optional title for the recording
|
|
26
|
+
* @param params.state - Optional JWT state for the recording
|
|
26
27
|
* @param params.removeOnEscape - Whether to remove the opened recorder on Escape presses. Default: true
|
|
27
28
|
* @param params.applyJamData - Custom function to apply recording data to URL
|
|
28
29
|
* @returns Unknown - TODO: expose a public API for opened recorders
|
|
29
30
|
*/
|
|
30
31
|
open(recordingId: string, params?: Pick<InitializeOptions, "applyJamData"> & {
|
|
31
32
|
jamTitle?: string | null;
|
|
33
|
+
state?: string | null;
|
|
32
34
|
/** Whether to remove the opened recorder on Escape presses. Default: true */
|
|
33
35
|
removeOnEscape?: boolean;
|
|
34
36
|
}): unknown;
|
|
@@ -54,8 +56,8 @@ type InitializeOptions = {
|
|
|
54
56
|
*/
|
|
55
57
|
openImmediately?: boolean | string | undefined | null;
|
|
56
58
|
/**
|
|
57
|
-
* Extract a `recordingId` and `
|
|
58
|
-
* Defaults to reading the `jam-recording` and `jam-
|
|
59
|
+
* Extract a `recordingId`, `jamTitle`, and `state` from the provided string.
|
|
60
|
+
* Defaults to reading the `jam-recording`, `jam-title`, and `jam-state` QSPs off the URL.
|
|
59
61
|
*/
|
|
60
62
|
parseJamData?(input: string): SerializableJamData | null;
|
|
61
63
|
/**
|
|
@@ -75,6 +77,8 @@ export type SerializableJamData = {
|
|
|
75
77
|
recordingId: string | null;
|
|
76
78
|
/** The human-readable title of the recording, or null if not present */
|
|
77
79
|
jamTitle: string | null;
|
|
80
|
+
/** The JWT state passed in the URL, or null if not present */
|
|
81
|
+
state?: string | null;
|
|
78
82
|
};
|
|
79
83
|
declare function resetForTesting(): void;
|
|
80
84
|
/** @internal - Reset SDK state for testing (only available in dev builds) */
|
package/lib/sdk.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function e(){const e=new EventTarget;return{addEventListener(t,n,r){e.addEventListener(t,n,r)},removeEventListener(t,n,r){e.removeEventListener(t,n,r)},dispatch:(t,n)=>e.dispatchEvent(new CustomEvent(t,{detail:n}))}}const t=(t,n=localStorage)=>{const r=`jam:${t}`,i=e();let o=null;try{o=n.getItem(r)}catch(e){}const a={count:Number.parseInt(o??"0",10)||0,addEventListener:i.addEventListener.bind(i),removeEventListener:i.removeEventListener.bind(i),update(e){const t=a.count;switch(e){case"increment":a.count+=1;break;case"decrement":a.count-=1;break;default:a.count=e}if(a.count<0&&(a.count=0),a.count!==t){try{n.setItem(r,`${a.count}`)}catch(e){}Object.assign(a,{count:a.count}),i.dispatch("update",a.count)}return a.count}};return window.addEventListener("storage",e=>{if(e.storageArea===n&&e.key===r){const t=Number.parseInt(e.newValue??"",10);Number.isNaN(t)||t===a.count||(a.count=t,i.dispatch("update",a.count))}}),a},n=e=>{try{const t=new URL(e);return{recordingId:t.searchParams.get("jam-recording"),jamTitle:t.searchParams.get("jam-title")}}catch(e){}return null},r={isInitialized:!1},i=void 0,o=e(),a=o.addEventListener.bind(o),c=o.removeEventListener.bind(o),d=()=>r.isInitialized;let s=null;function u({recorderRefCounter:e=t("numRecorders"),_loadRemoteScript:i=m,...o}={}){if(r.isInitialized)throw new Error("SDK already initialized.");Object.assign(r,{isInitialized:!0,recorderRefCounter:e,config:o,_loadRemoteScript:i}),e.count>0?p():e.addEventListener("update",p,{once:!0}),window.addEventListener("popstate",c);const a={apply(e,t,n){const r=Reflect.apply(e,t,n);return c(),r}};function c(){if(s)return;const e=r.config?.parseJamData??n,t="string"==typeof r.config?.openImmediately?r.config.openImmediately:e(window.location.href)?.recordingId;t&&l({openImmediately:!1!==r.config?.openImmediately&&t})}history.pushState=new Proxy(history.pushState,a),history.replaceState=new Proxy(history.replaceState,a),c()}async function l({...e}={}){if(s)return s;if(!r.isInitialized)throw new Error("SDK not initialized. Call initialize() first.");if(({Recorder:s}=await r._loadRemoteScript("recorder")),!s)throw new Error("Failed to load recorder script.");const{openImmediately:t,...n}={...r.config,...e},i="string"==typeof t?t:null;return s.initialize({...n,openImmediately:!i&&(t??!0)}),r.recorderRefCounter.update("increment"),window.addEventListener("pagehide",()=>{r.recorderRefCounter.update("decrement")}),i&&s.open(i,n),s}async function p(){if(!r.isInitialized||!r._loadRemoteScript)throw new Error("SDK not initialized. Call initialize() first.");const{Capture:e}=await r._loadRemoteScript("capture")??{};await(e?.initialize(r.config))}async function m(e){const t=`https://js.jam.dev/${e}.js`,n=await import(
|
|
1
|
+
function e(){const e=new EventTarget;return{addEventListener(t,n,r){e.addEventListener(t,n,r)},removeEventListener(t,n,r){e.removeEventListener(t,n,r)},dispatch:(t,n)=>e.dispatchEvent(new CustomEvent(t,{detail:n}))}}const t=(t,n=localStorage)=>{const r=`jam:${t}`,i=e();let o=null;try{o=n.getItem(r)}catch(e){}const a={count:Number.parseInt(o??"0",10)||0,addEventListener:i.addEventListener.bind(i),removeEventListener:i.removeEventListener.bind(i),update(e){const t=a.count;switch(e){case"increment":a.count+=1;break;case"decrement":a.count-=1;break;default:a.count=e}if(a.count<0&&(a.count=0),a.count!==t){try{n.setItem(r,`${a.count}`)}catch(e){}Object.assign(a,{count:a.count}),i.dispatch("update",a.count)}return a.count}};return window.addEventListener("storage",e=>{if(e.storageArea===n&&e.key===r){const t=Number.parseInt(e.newValue??"",10);Number.isNaN(t)||t===a.count||(a.count=t,i.dispatch("update",a.count))}}),a},n=e=>{try{const t=new URL(e);return{recordingId:t.searchParams.get("jam-recording"),jamTitle:t.searchParams.get("jam-title"),state:t.searchParams.get("jam-state")}}catch(e){}return null},r={isInitialized:!1},i=void 0,o=e(),a=o.addEventListener.bind(o),c=o.removeEventListener.bind(o),d=()=>r.isInitialized;let s=null;function u({recorderRefCounter:e=t("numRecorders"),_loadRemoteScript:i=m,...o}={}){if(r.isInitialized)throw new Error("SDK already initialized.");Object.assign(r,{isInitialized:!0,recorderRefCounter:e,config:o,_loadRemoteScript:i}),e.count>0?p():e.addEventListener("update",p,{once:!0}),window.addEventListener("popstate",c);const a={apply(e,t,n){const r=Reflect.apply(e,t,n);return c(),r}};function c(){if(s)return;const e=r.config?.parseJamData??n,t="string"==typeof r.config?.openImmediately?r.config.openImmediately:e(window.location.href)?.recordingId;t&&l({openImmediately:!1!==r.config?.openImmediately&&t})}history.pushState=new Proxy(history.pushState,a),history.replaceState=new Proxy(history.replaceState,a),c()}async function l({...e}={}){if(s)return s;if(!r.isInitialized)throw new Error("SDK not initialized. Call initialize() first.");if(({Recorder:s}=await r._loadRemoteScript("recorder")),!s)throw new Error("Failed to load recorder script.");const{openImmediately:t,...n}={...r.config,...e},i="string"==typeof t?t:null;return s.initialize({...n,openImmediately:!i&&(t??!0)}),r.recorderRefCounter.update("increment"),window.addEventListener("pagehide",()=>{r.recorderRefCounter.update("decrement")}),i&&s.open(i,n),s}async function p(){if(!r.isInitialized||!r._loadRemoteScript)throw new Error("SDK not initialized. Call initialize() first.");const{Capture:e}=await r._loadRemoteScript("capture")??{};await(e?.initialize(r.config))}async function m(e){const t=`https://js.jam.dev/${e}.js`,n=await import(
|
|
2
2
|
/* webpackIgnore: true */
|
|
3
3
|
/* @vite-ignore */
|
|
4
4
|
/* @rollup/plugin-dynamic-import-vars ignore */
|