instruckt 0.4.21 → 0.4.22

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.
@@ -2,10 +2,14 @@ type AnnotationIntent = 'fix' | 'change' | 'question' | 'approve';
2
2
  type AnnotationSeverity = 'blocking' | 'important' | 'suggestion';
3
3
  type AnnotationStatus = 'pending' | 'resolved' | 'dismissed';
4
4
  interface FrameworkContext {
5
- framework: 'livewire' | 'vue' | 'svelte' | 'react';
5
+ framework: 'livewire' | 'vue' | 'svelte' | 'react' | 'blade';
6
6
  component: string;
7
7
  data?: Record<string, unknown>;
8
+ source_file?: string;
9
+ source_line?: number;
8
10
  wire_id?: string;
11
+ class_name?: string;
12
+ render_line?: number;
9
13
  component_uid?: string;
10
14
  }
11
15
  interface BoundingBox {
@@ -58,7 +62,7 @@ interface InstrucktConfig {
58
62
  /** URL to POST annotations to. Default: '/instruckt' */
59
63
  endpoint: string;
60
64
  /** Framework adapters to activate. Default: auto-detect */
61
- adapters?: Array<'livewire' | 'vue' | 'svelte' | 'react'>;
65
+ adapters?: Array<'livewire' | 'vue' | 'svelte' | 'react' | 'blade'>;
62
66
  /** Theme preference. Default: 'auto' */
63
67
  theme?: 'light' | 'dark' | 'auto';
64
68
  /** Position of the toolbar. Default: 'bottom-right' */
@@ -2,10 +2,14 @@ type AnnotationIntent = 'fix' | 'change' | 'question' | 'approve';
2
2
  type AnnotationSeverity = 'blocking' | 'important' | 'suggestion';
3
3
  type AnnotationStatus = 'pending' | 'resolved' | 'dismissed';
4
4
  interface FrameworkContext {
5
- framework: 'livewire' | 'vue' | 'svelte' | 'react';
5
+ framework: 'livewire' | 'vue' | 'svelte' | 'react' | 'blade';
6
6
  component: string;
7
7
  data?: Record<string, unknown>;
8
+ source_file?: string;
9
+ source_line?: number;
8
10
  wire_id?: string;
11
+ class_name?: string;
12
+ render_line?: number;
9
13
  component_uid?: string;
10
14
  }
11
15
  interface BoundingBox {
@@ -58,7 +62,7 @@ interface InstrucktConfig {
58
62
  /** URL to POST annotations to. Default: '/instruckt' */
59
63
  endpoint: string;
60
64
  /** Framework adapters to activate. Default: auto-detect */
61
- adapters?: Array<'livewire' | 'vue' | 'svelte' | 'react'>;
65
+ adapters?: Array<'livewire' | 'vue' | 'svelte' | 'react' | 'blade'>;
62
66
  /** Theme preference. Default: 'auto' */
63
67
  theme?: 'light' | 'dark' | 'auto';
64
68
  /** Position of the toolbar. Default: 'bottom-right' */
@@ -2925,43 +2925,70 @@ function detect(el) {
2925
2925
  return null;
2926
2926
  }
2927
2927
  function getContext(el) {
2928
- var _a2, _b;
2928
+ var _a2, _b, _c, _d, _e;
2929
2929
  if (!isAvailable()) return null;
2930
2930
  const wireEl = detect(el);
2931
2931
  if (!wireEl) return null;
2932
2932
  const wireId = wireEl.getAttribute("wire:id");
2933
2933
  let componentName = "Unknown";
2934
+ let className;
2934
2935
  const snapshotAttr = wireEl.getAttribute("wire:snapshot");
2935
2936
  if (snapshotAttr) {
2936
2937
  try {
2937
2938
  const snapshot = JSON.parse(snapshotAttr);
2938
2939
  componentName = (_b = (_a2 = snapshot == null ? void 0 : snapshot.memo) == null ? void 0 : _a2.name) != null ? _b : "Unknown";
2940
+ className = (_e = (_c = snapshot == null ? void 0 : snapshot.memo) == null ? void 0 : _c.path) != null ? _e : (_d = snapshot == null ? void 0 : snapshot.memo) == null ? void 0 : _d.name;
2939
2941
  } catch (e) {
2940
2942
  }
2941
2943
  }
2942
2944
  return {
2943
2945
  framework: "livewire",
2944
2946
  component: componentName,
2945
- wire_id: wireId
2947
+ wire_id: wireId,
2948
+ class_name: className
2946
2949
  };
2947
2950
  }
2948
2951
 
2949
2952
  // src/adapters/vue.ts
2953
+ function isUserFile(file) {
2954
+ if (!file) return false;
2955
+ return !file.includes("node_modules");
2956
+ }
2957
+ function getInstanceFile(instance) {
2958
+ var _a2, _b, _c;
2959
+ return (_c = (_a2 = instance.type) == null ? void 0 : _a2.__file) != null ? _c : (_b = instance.$options) == null ? void 0 : _b.__file;
2960
+ }
2961
+ function getInstanceName(instance) {
2962
+ var _a2, _b, _c, _d, _e, _f, _g, _h;
2963
+ return (_h = (_g = (_e = (_c = (_a2 = instance.$options) == null ? void 0 : _a2.name) != null ? _c : (_b = instance.$options) == null ? void 0 : _b.__name) != null ? _e : (_d = instance.type) == null ? void 0 : _d.name) != null ? _g : (_f = instance.type) == null ? void 0 : _f.__name) != null ? _h : "Anonymous";
2964
+ }
2950
2965
  function detect2(el) {
2951
2966
  var _a2;
2967
+ let firstMatch = null;
2952
2968
  let node = el;
2953
2969
  while (node && node !== document.documentElement) {
2954
2970
  const instance = (_a2 = node.__vueParentComponent) != null ? _a2 : node.__vue__;
2955
- if (instance) return instance;
2971
+ if (instance) {
2972
+ const file = getInstanceFile(instance);
2973
+ if (isUserFile(file)) return instance;
2974
+ if (!firstMatch) firstMatch = instance;
2975
+ }
2956
2976
  node = node.parentElement;
2957
2977
  }
2958
- return null;
2978
+ if (firstMatch == null ? void 0 : firstMatch.parent) {
2979
+ let instance = firstMatch.parent;
2980
+ while (instance) {
2981
+ const file = getInstanceFile(instance);
2982
+ if (isUserFile(file)) return instance;
2983
+ instance = instance.parent;
2984
+ }
2985
+ }
2986
+ return firstMatch;
2959
2987
  }
2960
2988
  function getContext2(el) {
2961
- var _a2, _b, _c, _d, _e, _f, _g, _h;
2962
2989
  const instance = detect2(el);
2963
2990
  if (!instance) return null;
2964
- const name = (_h = (_g = (_e = (_c = (_a2 = instance.$options) == null ? void 0 : _a2.name) != null ? _c : (_b = instance.$options) == null ? void 0 : _b.__name) != null ? _e : (_d = instance.type) == null ? void 0 : _d.name) != null ? _g : (_f = instance.type) == null ? void 0 : _f.__name) != null ? _h : "Anonymous";
2991
+ const name = getInstanceName(instance);
2965
2992
  const data = {};
2966
2993
  if (instance.props) {
2967
2994
  Object.assign(data, instance.props);
@@ -2977,9 +3004,11 @@ function getContext2(el) {
2977
3004
  }
2978
3005
  }
2979
3006
  }
3007
+ const file = getInstanceFile(instance);
2980
3008
  return {
2981
3009
  framework: "vue",
2982
3010
  component: name,
3011
+ source_file: file,
2983
3012
  component_uid: instance.uid !== void 0 ? String(instance.uid) : void 0,
2984
3013
  data
2985
3014
  };
@@ -3003,6 +3032,7 @@ function getContext3(el) {
3003
3032
  return {
3004
3033
  framework: "svelte",
3005
3034
  component,
3035
+ source_file: filePath || void 0,
3006
3036
  data: filePath ? { file: filePath } : void 0
3007
3037
  };
3008
3038
  }
@@ -3016,20 +3046,31 @@ function getFiberKey(el) {
3016
3046
  }
3017
3047
  return null;
3018
3048
  }
3019
- function getComponentName(fiber) {
3049
+ function isUserSource(source) {
3050
+ if (!source) return false;
3051
+ return !source.fileName.includes("node_modules");
3052
+ }
3053
+ function findComponent(fiber) {
3054
+ let firstMatch = null;
3020
3055
  let node = fiber;
3021
3056
  while (node) {
3022
3057
  const { type } = node;
3058
+ let name = null;
3023
3059
  if (typeof type === "function" && type.name) {
3024
- const name = type.name;
3025
- if (name[0] === name[0].toUpperCase() && name.length > 1) return name;
3060
+ const n = type.name;
3061
+ if (n[0] === n[0].toUpperCase() && n.length > 1) name = n;
3026
3062
  }
3027
- if (typeof type === "object" && type !== null && type.displayName) {
3028
- return type.displayName;
3063
+ if (!name && typeof type === "object" && type !== null && type.displayName) {
3064
+ name = type.displayName;
3065
+ }
3066
+ if (name) {
3067
+ const info = { name, source: node._debugSource };
3068
+ if (isUserSource(node._debugSource)) return info;
3069
+ if (!firstMatch) firstMatch = info;
3029
3070
  }
3030
3071
  node = node.return;
3031
3072
  }
3032
- return "Component";
3073
+ return firstMatch != null ? firstMatch : { name: "Component" };
3033
3074
  }
3034
3075
  function getProps(fiber) {
3035
3076
  var _a2, _b;
@@ -3052,9 +3093,15 @@ function getContext4(el) {
3052
3093
  if (key) {
3053
3094
  const fiber = node[key];
3054
3095
  if (fiber) {
3055
- const component = getComponentName(fiber);
3096
+ const { name, source } = findComponent(fiber);
3056
3097
  const data = getProps(fiber);
3057
- return { framework: "react", component, data };
3098
+ return {
3099
+ framework: "react",
3100
+ component: name,
3101
+ source_file: source == null ? void 0 : source.fileName,
3102
+ source_line: source == null ? void 0 : source.lineNumber,
3103
+ data
3104
+ };
3058
3105
  }
3059
3106
  }
3060
3107
  node = node.parentElement;
@@ -3062,6 +3109,30 @@ function getContext4(el) {
3062
3109
  return null;
3063
3110
  }
3064
3111
 
3112
+ // src/adapters/blade.ts
3113
+ function getTrackedViews() {
3114
+ var _a2;
3115
+ const el = document.getElementById("instruckt-views");
3116
+ if (!el) return [];
3117
+ try {
3118
+ return JSON.parse((_a2 = el.textContent) != null ? _a2 : "[]");
3119
+ } catch (e) {
3120
+ return [];
3121
+ }
3122
+ }
3123
+ function getContext5(_el) {
3124
+ var _a2;
3125
+ const views = getTrackedViews();
3126
+ if (views.length === 0) return null;
3127
+ const pageView = views.length > 1 ? (_a2 = views.find((v) => !v.name.startsWith("layouts.") && !v.name.startsWith("components."))) != null ? _a2 : views[views.length - 1] : views[0];
3128
+ return {
3129
+ framework: "blade",
3130
+ component: pageView.name,
3131
+ source_file: pageView.file,
3132
+ data: { views: views.map((v) => v.file) }
3133
+ };
3134
+ }
3135
+
3065
3136
  // src/instruckt.ts
3066
3137
  function pageKey() {
3067
3138
  return window.location.pathname;
@@ -3170,7 +3241,7 @@ var _Instruckt = class _Instruckt {
3170
3241
  this.showAnnotationPopup(pending);
3171
3242
  };
3172
3243
  this.config = __spreadValues({
3173
- adapters: ["livewire", "vue", "svelte", "react"],
3244
+ adapters: ["livewire", "vue", "svelte", "react", "blade"],
3174
3245
  theme: "auto",
3175
3246
  position: "bottom-right"
3176
3247
  }, config);
@@ -3264,12 +3335,10 @@ var _Instruckt = class _Instruckt {
3264
3335
  this.loadFromStorage();
3265
3336
  try {
3266
3337
  const remote = await this.api.getAnnotations();
3267
- if (remote.length > 0) {
3268
- const remoteIds = new Set(remote.map((a) => a.id));
3269
- const localOnly = this.annotations.filter((a) => !remoteIds.has(a.id));
3270
- this.annotations = [...remote, ...localOnly];
3271
- this.saveToStorage();
3272
- }
3338
+ const remoteIds = new Set(remote.map((a) => a.id));
3339
+ const localOnly = this.annotations.filter((a) => !remoteIds.has(a.id));
3340
+ this.annotations = [...remote, ...localOnly];
3341
+ this.saveToStorage();
3273
3342
  } catch (e) {
3274
3343
  }
3275
3344
  this.syncMarkers();
@@ -3552,6 +3621,10 @@ var _Instruckt = class _Instruckt {
3552
3621
  const ctx = getContext4(el);
3553
3622
  if (ctx) return ctx;
3554
3623
  }
3624
+ if (adapters.includes("blade")) {
3625
+ const ctx = getContext5(el);
3626
+ if (ctx) return ctx;
3627
+ }
3555
3628
  return null;
3556
3629
  }
3557
3630
  // ── Submit ────────────────────────────────────────────────────
@@ -3727,11 +3800,15 @@ No open annotations.`;
3727
3800
  lines.push("");
3728
3801
  const hPrefix = multiPage ? "###" : "##";
3729
3802
  annotations.forEach((a, i) => {
3730
- var _a2, _b, _c;
3803
+ var _a2, _b, _c, _d;
3731
3804
  const componentSuffix = ((_a2 = a.framework) == null ? void 0 : _a2.component) ? ` in \`${a.framework.component}\`` : "";
3732
3805
  lines.push(`${hPrefix} ${i + 1}. ${a.comment}`);
3806
+ lines.push(`- ID: \`${a.id}\``);
3733
3807
  lines.push(`- Element: \`${a.element}\`${componentSuffix}`);
3734
- if ((_c = (_b = a.framework) == null ? void 0 : _b.data) == null ? void 0 : _c.file) {
3808
+ if ((_b = a.framework) == null ? void 0 : _b.source_file) {
3809
+ const loc = a.framework.source_line ? `${a.framework.source_file}:${a.framework.source_line}` : a.framework.source_file;
3810
+ lines.push(`- Source: \`${loc}\``);
3811
+ } else if ((_d = (_c = a.framework) == null ? void 0 : _c.data) == null ? void 0 : _d.file) {
3735
3812
  lines.push(`- File: \`${a.framework.data.file}\``);
3736
3813
  }
3737
3814
  if (a.cssClasses) {