@inpageedit/core 0.12.1 → 0.13.0-alpha.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.
Files changed (127) hide show
  1. package/LICENSE +20 -20
  2. package/dist/BasePlugin-Bf2UuIHF.js +64 -0
  3. package/dist/BasePlugin-Bf2UuIHF.js.map +1 -0
  4. package/dist/IconQuickEdit-CMCQncyj.js.map +1 -1
  5. package/dist/InputBox-nQKtiWtZ.js.map +1 -1
  6. package/dist/{PluginPrefSync-Ziogy_o-.js → PluginPrefSync-Dn1Xsiqz.js} +6 -4
  7. package/dist/PluginPrefSync-Dn1Xsiqz.js.map +1 -0
  8. package/dist/{PluginStoreApp-Bnvyl-Oc.js → PluginStoreApp-CpOLArL7.js} +2 -2
  9. package/dist/{PluginStoreApp-Bnvyl-Oc.js.map → PluginStoreApp-CpOLArL7.js.map} +1 -1
  10. package/dist/Preferences-DS4-CFWe.js.map +1 -1
  11. package/dist/WatchlistAction-BbNAyryN.js +5 -0
  12. package/dist/WatchlistAction-BbNAyryN.js.map +1 -0
  13. package/dist/components/index.js.map +1 -1
  14. package/dist/endpoints-DgyuoRZd.js +1507 -0
  15. package/dist/endpoints-DgyuoRZd.js.map +1 -0
  16. package/dist/{index-BvuaLEFc.js → index-2RfILgXm.js} +11 -10
  17. package/dist/{index-BvuaLEFc.js.map → index-2RfILgXm.js.map} +1 -1
  18. package/dist/{index-eARjMi7f.js → index-B7c6jL9x.js} +25 -23
  19. package/dist/index-B7c6jL9x.js.map +1 -0
  20. package/dist/{index-zHTGCjfF.js → index-BJ7_Q1mB.js} +8 -7
  21. package/dist/{index-zHTGCjfF.js.map → index-BJ7_Q1mB.js.map} +1 -1
  22. package/dist/{index-Dnmv-xDn.js → index-BNh95-x2.js} +37 -49
  23. package/dist/index-BNh95-x2.js.map +1 -0
  24. package/dist/{index-B3FUDhxl.js → index-BQ-cHWkJ.js} +15 -16
  25. package/dist/{index-B3FUDhxl.js.map → index-BQ-cHWkJ.js.map} +1 -1
  26. package/dist/{index-B3YJdjxo.js → index-BwdWyHLe.js} +77 -76
  27. package/dist/{index-B3YJdjxo.js.map → index-BwdWyHLe.js.map} +1 -1
  28. package/dist/{index-Ccr3YhkP.js → index-CCRMmnwk.js} +10 -9
  29. package/dist/index-CCRMmnwk.js.map +1 -0
  30. package/dist/index-CG38LlAh.js.map +1 -1
  31. package/dist/index-CM_6yF2v.js.map +1 -1
  32. package/dist/index-C_BIsubQ.js +3744 -0
  33. package/dist/index-C_BIsubQ.js.map +1 -0
  34. package/dist/{index-Bd70aDMT.js → index-CnIpUF9x.js} +7 -6
  35. package/dist/{index-Bd70aDMT.js.map → index-CnIpUF9x.js.map} +1 -1
  36. package/dist/{index-D5zX93bn.js → index-CyG7_IYz.js} +47 -45
  37. package/dist/index-CyG7_IYz.js.map +1 -0
  38. package/dist/index-DD5CVCfD.js.map +1 -1
  39. package/dist/{index-BRjEc8b8.js → index-eSlbrNqF.js} +6 -6
  40. package/dist/{index-BRjEc8b8.js.map → index-eSlbrNqF.js.map} +1 -1
  41. package/dist/index.d.ts +1742 -31
  42. package/dist/index.js +73 -9
  43. package/dist/index.js.map +1 -1
  44. package/dist/makeCallable-LDU0xZMJ.js.map +1 -1
  45. package/dist/models/index.js +486 -0
  46. package/dist/models/index.js.map +1 -0
  47. package/dist/noop-ClDc6zv4.js.map +1 -1
  48. package/dist/plugins/index.js +23 -0
  49. package/dist/plugins/index.js.map +1 -0
  50. package/dist/services/index.js +16 -0
  51. package/dist/services/index.js.map +1 -0
  52. package/dist/style.css +1 -1
  53. package/dist/vueHooks-l04s8cIl.js.map +1 -1
  54. package/lib/index.umd.js +10 -10
  55. package/lib/index.umd.js.map +1 -1
  56. package/package.json +23 -30
  57. package/dist/InPageEdit.d.ts +0 -42
  58. package/dist/PluginPrefSync-Ziogy_o-.js.map +0 -1
  59. package/dist/__test__/utils/constants.d.ts +0 -3
  60. package/dist/components/ActionButton.d.ts +0 -6
  61. package/dist/components/CheckBox.d.ts +0 -10
  62. package/dist/components/Icon/IconEdit.d.ts +0 -2
  63. package/dist/components/Icon/IconQuickEdit.d.ts +0 -2
  64. package/dist/components/InputBox.d.ts +0 -11
  65. package/dist/components/MBox/index.d.ts +0 -14
  66. package/dist/components/MwUserLinks.d.ts +0 -6
  67. package/dist/components/ProgressBar/index.d.ts +0 -7
  68. package/dist/components/RadioBox.d.ts +0 -10
  69. package/dist/components/TabView/index.d.ts +0 -19
  70. package/dist/components/TwinSwapInput/index.d.ts +0 -19
  71. package/dist/components/index.d.ts +0 -8
  72. package/dist/components/utils.d.ts +0 -4
  73. package/dist/constants/endpoints.d.ts +0 -8
  74. package/dist/decorators/Preferences.d.ts +0 -35
  75. package/dist/index-Ccr3YhkP.js.map +0 -1
  76. package/dist/index-D5zX93bn.js.map +0 -1
  77. package/dist/index-DgQNTfPR.js +0 -5829
  78. package/dist/index-DgQNTfPR.js.map +0 -1
  79. package/dist/index-Dnmv-xDn.js.map +0 -1
  80. package/dist/index-eARjMi7f.js.map +0 -1
  81. package/dist/models/MemoryStorage.d.ts +0 -10
  82. package/dist/models/WikiPage/index.d.ts +0 -76
  83. package/dist/models/WikiPage/types/PageInfo.d.ts +0 -58
  84. package/dist/models/WikiPage/types/PageParseData.d.ts +0 -17
  85. package/dist/models/WikiPage/types/WatchlistAction.d.ts +0 -6
  86. package/dist/models/WikiTitle/index.d.ts +0 -89
  87. package/dist/models/WikiTitle/index.spec.d.ts +0 -1
  88. package/dist/plugins/BasePlugin.d.ts +0 -25
  89. package/dist/plugins/_debug/index.d.ts +0 -8
  90. package/dist/plugins/analytics/index.d.ts +0 -41
  91. package/dist/plugins/in-article-links/index.d.ts +0 -44
  92. package/dist/plugins/plugin-store/index.d.ts +0 -56
  93. package/dist/plugins/plugin-store/schema.d.ts +0 -41
  94. package/dist/plugins/preferences-ui/PluginPrefSync.d.ts +0 -28
  95. package/dist/plugins/preferences-ui/index.d.ts +0 -48
  96. package/dist/plugins/quick-diff/components/DiffTable.d.ts +0 -23
  97. package/dist/plugins/quick-diff/index.d.ts +0 -85
  98. package/dist/plugins/quick-edit/index.d.ts +0 -79
  99. package/dist/plugins/quick-move/index.d.ts +0 -47
  100. package/dist/plugins/quick-preview/index.d.ts +0 -37
  101. package/dist/plugins/quick-redirect/index.d.ts +0 -48
  102. package/dist/plugins/toolbox/index.d.ts +0 -65
  103. package/dist/polyfills/Promise.withResolvers.d.ts +0 -5
  104. package/dist/polyfills/index.d.ts +0 -0
  105. package/dist/services/ApiService.d.ts +0 -14
  106. package/dist/services/CurrentPageService.d.ts +0 -28
  107. package/dist/services/ModalService.d.ts +0 -27
  108. package/dist/services/PreferencesService.d.ts +0 -94
  109. package/dist/services/ResourceLoaderService.d.ts +0 -17
  110. package/dist/services/WikiMetadataService.d.ts +0 -108
  111. package/dist/services/WikiPageService.d.ts +0 -20
  112. package/dist/services/WikiTitleService.d.ts +0 -70
  113. package/dist/services/storage/index.d.ts +0 -40
  114. package/dist/services/storage/managers/IDBStorageManager.d.ts +0 -28
  115. package/dist/services/storage/managers/LocalStorageManager.d.ts +0 -27
  116. package/dist/types/WikiMetadata.d.ts +0 -131
  117. package/dist/utils/computeable.d.ts +0 -2
  118. package/dist/utils/defineAsyncPlugin.d.ts +0 -2
  119. package/dist/utils/interpolate.d.ts +0 -20
  120. package/dist/utils/interpolate.spec.d.ts +0 -1
  121. package/dist/utils/makeCallable.d.ts +0 -3
  122. package/dist/utils/noop.d.ts +0 -1
  123. package/dist/utils/sleep.d.ts +0 -1
  124. package/dist/utils/string.d.ts +0 -7
  125. package/dist/utils/url.d.ts +0 -24
  126. package/dist/utils/vueHooks.d.ts +0 -6
  127. package/dist/utils/vueReactivity.d.ts +0 -2
@@ -1,57 +1,58 @@
1
- import { j as l, F as q, P as j } from "./index-CM_6yF2v.js";
2
- import { B as S, I as E, S as P } from "./index-DgQNTfPR.js";
3
- import { R as Q } from "./Preferences-DS4-CFWe.js";
1
+ import { j as l, F as q, P as S } from "./index-CM_6yF2v.js";
2
+ import { R as j } from "./Preferences-DS4-CFWe.js";
3
+ import { B as E } from "./BasePlugin-Bf2UuIHF.js";
4
4
  import { m as C } from "./makeCallable-LDU0xZMJ.js";
5
- var F = Object.create, w = Object.defineProperty, T = Object.getOwnPropertyDescriptor, f = (t, i) => (i = Symbol[t]) ? i : Symbol.for("Symbol." + t), x = (t) => {
5
+ import { I as F, S as f } from "./endpoints-DgyuoRZd.js";
6
+ var I = Object.create, w = Object.defineProperty, O = Object.getOwnPropertyDescriptor, P = (t, i) => (i = Symbol[t]) ? i : Symbol.for("Symbol." + t), x = (t) => {
6
7
  throw TypeError(t);
7
- }, B = (t, i, r) => i in t ? w(t, i, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[i] = r, D = (t, i) => w(t, "name", { value: i, configurable: !0 }), I = (t) => [, , , F(t?.[f("metadata")] ?? null)], O = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], g = (t) => t !== void 0 && typeof t != "function" ? x("Function expected") : t, z = (t, i, r, c, e) => ({ kind: O[t], name: i, metadata: c, addInitializer: (s) => r._ ? x("Already initialized") : e.push(g(s || null)) }), N = (t, i) => B(i, f("metadata"), t[3]), M = (t, i, r, c) => {
8
- for (var e = 0, s = t[i >> 1], n = s && s.length; e < n; e++) s[e].call(r);
8
+ }, Q = (t, i, r) => i in t ? w(t, i, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[i] = r, T = (t, i) => w(t, "name", { value: i, configurable: !0 }), z = (t) => [, , , I(t?.[P("metadata")] ?? null)], B = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], g = (t) => t !== void 0 && typeof t != "function" ? x("Function expected") : t, D = (t, i, r, c, e) => ({ kind: B[t], name: i, metadata: c, addInitializer: (a) => r._ ? x("Already initialized") : e.push(g(a || null)) }), N = (t, i) => Q(i, P("metadata"), t[3]), M = (t, i, r, c) => {
9
+ for (var e = 0, a = t[i >> 1], s = a && a.length; e < s; e++) a[e].call(r);
9
10
  return c;
10
- }, R = (t, i, r, c, e, s) => {
11
- var n, o, u, a = i & 7, k = !1, _ = 0, y = t[_] || (t[_] = []), d = a && (e = e.prototype, a < 5 && (a > 3 || !k) && T(e, r));
12
- D(e, r);
13
- for (var p = c.length - 1; p >= 0; p--)
14
- u = z(a, r, o = {}, t[3], y), n = (0, c[p])(e, u), o._ = 1, g(n) && (e = n);
15
- return N(t, e), d && w(e, r, d), k ? a ^ 4 ? s : d : e;
16
- }, b, h, m;
17
- b = [E(["api", "wikiPage", "modal", "preferences"]), Q(
18
- P.object({
19
- "quickPreview.keyshortcut": P.string().default("ctrl-p").description("Key shortcut to open quick preview in quick edit modal")
11
+ }, R = (t, i, r, c, e, a) => {
12
+ var s, o, u, n = i & 7, h = !1, k = 0, y = t[k] || (t[k] = []), p = n && (e = e.prototype, n < 5 && (n > 3 || !h) && O(e, r));
13
+ T(e, r);
14
+ for (var v = c.length - 1; v >= 0; v--)
15
+ u = D(n, r, o = {}, t[3], y), s = (0, c[v])(e, u), o._ = 1, g(s) && (e = s);
16
+ return N(t, e), p && w(e, r, p), h ? n ^ 4 ? a : p : e;
17
+ }, m, _, b;
18
+ m = [F(["api", "wikiPage", "modal", "preferences"]), j(
19
+ f.object({
20
+ "quickPreview.keyshortcut": f.string().default("ctrl-p").description("Key shortcut to open quick preview in quick edit modal")
20
21
  }).extra("category", "editor").description("Quick preview options")
21
22
  )];
22
- class v extends (m = S) {
23
+ class d extends (b = E) {
23
24
  constructor(i) {
24
25
  super(i, {}, "quickPreview"), this.ctx = i, this.ctx.set("quickPreview", C(this, "previewWikitext"));
25
26
  }
26
27
  start() {
27
- this.ctx.on("quick-edit/wiki-page", this.injectQuickEdit.bind(this)), this.ctx.on("quick-delete/wiki-page", this.injectQuickDelete.bind(this));
28
+ this.ctx.on("quick-edit/wiki-page", this.injectQuickEdit.bind(this));
28
29
  }
29
30
  stop() {
30
31
  }
31
- previewWikitext(i, r, c, e, s) {
32
+ previewWikitext(i, r, c, e, a) {
32
33
  return c ||= this.ctx.wikiPage.newBlankPage({
33
34
  title: "API"
34
35
  }), (!e || e.isDestroyed) && (e = this.ctx.modal.createObject({
35
36
  className: "in-page-edit ipe-quickPreview",
36
37
  sizeClass: "large",
37
38
  center: !1,
38
- ...s
39
- }).init()), e.show(), e.setTitle("Preview - Loading..."), e.setContent(/* @__PURE__ */ l(j, {})), e.bringToFront(), this.ctx.emit("quick-preview/show-modal", {
39
+ ...a
40
+ }).init()), e.show(), e.setTitle("Preview - Loading..."), e.setContent(/* @__PURE__ */ l(S, {})), e.bringToFront(), this.ctx.emit("quick-preview/show-modal", {
40
41
  ctx: this.ctx,
41
42
  text: i,
42
43
  modal: e,
43
44
  wikiPage: c
44
- }), c.preview(i, r).then((n) => {
45
+ }), c.preview(i, r).then((s) => {
45
46
  const {
46
47
  data: { parse: o }
47
- } = n;
48
+ } = s;
48
49
  e.setTitle(`Preview - ${o.title}`);
49
50
  let u = null;
50
51
  e.setContent(
51
52
  /* @__PURE__ */ l("section", { children: /* @__PURE__ */ l(
52
53
  "div",
53
54
  {
54
- ref: (a) => u = a,
55
+ ref: (n) => u = n,
55
56
  className: "mw-parser-output",
56
57
  innerHTML: o.text
57
58
  }
@@ -63,11 +64,11 @@ class v extends (m = S) {
63
64
  text: i,
64
65
  parseData: o
65
66
  });
66
- }).catch((n) => {
67
+ }).catch((s) => {
67
68
  e.setTitle("Preview - Failed"), e.setContent(
68
69
  /* @__PURE__ */ l(q, { children: [
69
70
  /* @__PURE__ */ l("p", { children: "Failed to preview" }),
70
- /* @__PURE__ */ l("p", { children: n instanceof Error ? n.message : String(n) })
71
+ /* @__PURE__ */ l("p", { children: s instanceof Error ? s.message : String(s) })
71
72
  ] })
72
73
  );
73
74
  }), e;
@@ -81,14 +82,14 @@ class v extends (m = S) {
81
82
  className: "btn btn-secondary",
82
83
  keyPress: await this.ctx.preferences.get("quickPreview.keyshortcut.quickEdit") || void 0,
83
84
  method: () => {
84
- let s = r.get$content().querySelector('textarea[name="text"]')?.value || "";
85
+ let a = r.get$content().querySelector('textarea[name="text"]')?.value || "";
85
86
  if (i.section === "new") {
86
- const n = r.get$content().querySelector('input[name="summary"]')?.value;
87
- n && (s = `==${n}==
88
- ${s}`);
87
+ const s = r.get$content().querySelector('input[name="summary"]')?.value;
88
+ s && (a = `==${s}==
89
+ ${a}`);
89
90
  }
90
91
  e = this.previewWikitext(
91
- s,
92
+ a,
92
93
  void 0,
93
94
  c,
94
95
  e,
@@ -104,24 +105,11 @@ ${s}`);
104
105
  e?.destroy(), e = void 0;
105
106
  });
106
107
  }
107
- injectQuickDelete({ ctx: i, modal: r, wikiPage: c }) {
108
- r.addButton(
109
- {
110
- label: "Preview",
111
- side: "left",
112
- className: "btn btn-secondary",
113
- method: () => {
114
- this.logger.warn("To be implemented: preview wikitext for quick delete");
115
- }
116
- },
117
- 2
118
- );
119
- }
120
108
  }
121
- h = I(m);
122
- v = R(h, 0, "PluginQuickPreview", b, v);
123
- M(h, 1, v);
109
+ _ = z(b);
110
+ d = R(_, 0, "PluginQuickPreview", m, d);
111
+ M(_, 1, d);
124
112
  export {
125
- v as PluginQuickPreview
113
+ d as PluginQuickPreview
126
114
  };
127
- //# sourceMappingURL=index-Dnmv-xDn.js.map
115
+ //# sourceMappingURL=index-BNh95-x2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BNh95-x2.js","sources":["../src/plugins/quick-preview/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit'\nimport { type QuickEditEventPayload } from '@/plugins/quick-edit'\nimport { IWikiPage } from '@/models/WikiPage'\nimport { MwApiParams } from 'wiki-saikou'\nimport { PageParseData } from '@/models/WikiPage/types/PageParseData'\nimport { IPEModal, IPEModalOptions } from '@inpageedit/modal'\n\ninterface QuickPreviewEventPayload {\n ctx: InPageEdit\n modal: IPEModal\n wikiPage: IWikiPage\n text: string\n parseData: PageParseData\n}\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickPreview: PluginQuickPreview & {\n // for backward compatibility\n (\n ...args: Parameters<PluginQuickPreview['previewWikitext']>\n ): ReturnType<PluginQuickPreview['previewWikitext']>\n }\n }\n interface Events {\n 'quick-preview/show-modal'(payload: Omit<QuickPreviewEventPayload, 'parseData'>): void\n 'quick-preview/loaded'(payload: QuickPreviewEventPayload): void\n }\n interface PreferencesMap {\n 'quickPreview.keyshortcut.quickEdit': string\n 'quickPreview.keyshortcut.quickDelete': string\n }\n}\n\n@Inject(['api', 'wikiPage', 'modal', 'preferences'])\n@RegisterPreferences(\n Schema.object({\n 'quickPreview.keyshortcut': Schema.string()\n .default('ctrl-p')\n .description('Key shortcut to open quick preview in quick edit modal'),\n })\n .extra('category', 'editor')\n .description('Quick preview options')\n)\nexport class PluginQuickPreview extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quickPreview')\n this.ctx.set('quickPreview', makeCallable(this, 'previewWikitext'))\n }\n\n protected start(): Promise<void> | void {\n this.ctx.on('quick-edit/wiki-page', this.injectQuickEdit.bind(this))\n }\n\n protected stop(): Promise<void> | void {}\n\n previewWikitext(\n text: string,\n params?: MwApiParams,\n wikiPage?: IWikiPage,\n modal?: IPEModal,\n modalOptions?: Partial<IPEModalOptions>\n ) {\n wikiPage ||= this.ctx.wikiPage.newBlankPage({\n title: 'API',\n })\n\n if (!modal || modal.isDestroyed) {\n modal = this.ctx.modal\n .createObject({\n className: 'in-page-edit ipe-quickPreview',\n sizeClass: 'large',\n center: false,\n ...modalOptions,\n })\n .init()\n }\n\n modal.show()\n modal.setTitle('Preview - Loading...')\n modal.setContent(<ProgressBar />)\n modal.bringToFront()\n this.ctx.emit('quick-preview/show-modal', {\n ctx: this.ctx,\n text,\n modal,\n wikiPage,\n })\n\n wikiPage\n .preview(text, params)\n .then((ret) => {\n const {\n data: { parse },\n } = ret\n modal.setTitle(`Preview - ${parse.title}`)\n let outputRef: HTMLElement | null = null\n modal.setContent(\n (\n <section>\n <div\n ref={(el) => (outputRef = el)}\n className=\"mw-parser-output\"\n innerHTML={parse.text}\n ></div>\n </section>\n ) as HTMLElement\n )\n window.mw?.hook('wikipage.content').fire($(outputRef!))\n this.ctx.emit('quick-preview/loaded', {\n ctx: this.ctx,\n modal,\n wikiPage,\n text,\n parseData: parse,\n })\n })\n .catch((error) => {\n modal.setTitle('Preview - Failed')\n modal.setContent(\n <>\n <p>Failed to preview</p>\n <p>{error instanceof Error ? error.message : String(error)}</p>\n </>\n )\n })\n\n return modal\n }\n\n private async injectQuickEdit({ options, modal, wikiPage }: QuickEditEventPayload) {\n let latestPreviewModal: IPEModal | undefined = undefined\n modal.addButton(\n {\n label: 'Preview',\n side: 'left',\n className: 'btn btn-secondary',\n keyPress:\n (await this.ctx.preferences.get('quickPreview.keyshortcut.quickEdit')) || undefined,\n method: () => {\n let wikitext =\n (modal.get$content().querySelector<HTMLTextAreaElement>('textarea[name=\"text\"]')\n ?.value as string) || ''\n if (options.section === 'new') {\n const title = modal\n .get$content()\n .querySelector<HTMLInputElement>('input[name=\"summary\"]')?.value\n if (title) {\n wikitext = `==${title}==\\n${wikitext}`\n }\n }\n\n latestPreviewModal = this.previewWikitext(\n wikitext,\n undefined,\n wikiPage,\n latestPreviewModal,\n {\n backdrop: false,\n draggable: true,\n }\n )\n },\n },\n 1\n )\n modal.on(modal.Event.Close, () => {\n latestPreviewModal?.destroy()\n latestPreviewModal = undefined\n })\n }\n}\n"],"names":["_PluginQuickPreview_decorators","_init","_a","Inject","RegisterPreferences","Schema","PluginQuickPreview","BasePlugin","ctx","makeCallable","text","params","wikiPage","modal","modalOptions","jsx","ProgressBar","ret","parse","outputRef","el","error","jsxs","Fragment","options","latestPreviewModal","wikitext","title","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
@@ -1,19 +1,20 @@
1
1
  import { j as n } from "./index-CM_6yF2v.js";
2
- import { B as I, S as p, E as b, p as x, a as P, I as U } from "./index-DgQNTfPR.js";
3
- var q = Object.create, _ = Object.defineProperty, B = Object.getOwnPropertyDescriptor, v = (i, e) => (e = Symbol[i]) ? e : Symbol.for("Symbol." + i), w = (i) => {
2
+ import { S as p, E as b, p as I, I as x } from "./endpoints-DgyuoRZd.js";
3
+ import { B as P, p as U } from "./BasePlugin-Bf2UuIHF.js";
4
+ var B = Object.create, f = Object.defineProperty, q = Object.getOwnPropertyDescriptor, v = (i, e) => (e = Symbol[i]) ? e : Symbol.for("Symbol." + i), w = (i) => {
4
5
  throw TypeError(i);
5
- }, L = (i, e, t) => e in i ? _(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, N = (i, e) => _(i, "name", { value: e, configurable: !0 }), T = (i) => [, , , q(i?.[v("metadata")] ?? null)], D = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], k = (i) => i !== void 0 && typeof i != "function" ? w("Function expected") : i, O = (i, e, t, a, s) => ({ kind: D[i], name: e, metadata: a, addInitializer: (r) => t._ ? w("Already initialized") : s.push(k(r || null)) }), j = (i, e) => L(e, v("metadata"), i[3]), C = (i, e, t, a) => {
6
+ }, L = (i, e, t) => e in i ? f(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, N = (i, e) => f(i, "name", { value: e, configurable: !0 }), T = (i) => [, , , B(i?.[v("metadata")] ?? null)], D = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], k = (i) => i !== void 0 && typeof i != "function" ? w("Function expected") : i, O = (i, e, t, a, s) => ({ kind: D[i], name: e, metadata: a, addInitializer: (r) => t._ ? w("Already initialized") : s.push(k(r || null)) }), j = (i, e) => L(e, v("metadata"), i[3]), C = (i, e, t, a) => {
6
7
  for (var s = 0, r = i[e >> 1], c = r && r.length; s < c; s++) r[s].call(t);
7
8
  return a;
8
9
  }, M = (i, e, t, a, s, r) => {
9
- var c, d, h, o = e & 7, l = !1, y = 0, A = i[y] || (i[y] = []), u = o && (s = s.prototype, o < 5 && (o > 3 || !l) && B(s, t));
10
+ var c, d, h, o = e & 7, l = !1, y = 0, A = i[y] || (i[y] = []), u = o && (s = s.prototype, o < 5 && (o > 3 || !l) && q(s, t));
10
11
  N(s, t);
11
12
  for (var g = a.length - 1; g >= 0; g--)
12
13
  h = O(o, t, d = {}, i[3], A), c = (0, a[g])(s, h), d._ = 1, k(c) && (s = c);
13
- return j(i, s), u && _(s, t, u), l ? o ^ 4 ? r : u : s;
14
- }, E, f, S;
15
- E = [U(["wiki", "preferences"])];
16
- class m extends (S = I) {
14
+ return j(i, s), u && f(s, t, u), l ? o ^ 4 ? r : u : s;
15
+ }, E, _, S;
16
+ E = [x(["wiki", "preferences"])];
17
+ class m extends (S = P) {
17
18
  // 1分钟
18
19
  constructor(e) {
19
20
  super(e, {}, "analytics"), this.ctx = e, this._usages = [], this._timer = null, this.MAX_QUEUE_SIZE = 50, this.INTERVAL_MS = 60 * 1e3, this._setupTimer(), this._registerUnloadHandler(), this._showConfirmNotify(), this._initPluginListeners(), e.set("analytics", this);
@@ -120,9 +121,7 @@ class m extends (S = I) {
120
121
  _initPluginListeners() {
121
122
  const e = this.ctx;
122
123
  e.on("in-article-links/anchor-clicked", (t) => {
123
- this.addEvent("in-article-links", x(t.action));
124
- }), e.on("quick-delete/submit", (t) => {
125
- this.addEvent("quick-delete", "submit", t.wikiPage.title);
124
+ this.addEvent("in-article-links", U(t.action));
126
125
  }), e.on("quick-diff/loaded", (t) => {
127
126
  this.addEvent("quick-diff", "loaded", t.compare.fromtitle);
128
127
  }), e.on("quick-redirect/submit", (t) => {
@@ -165,7 +164,7 @@ class m extends (S = I) {
165
164
  return this.logger.debug("Beacon sent successfully", a), !0;
166
165
  {
167
166
  this.logger.debug("Beacon failed, sending via XMLHttpRequest");
168
- const { promise: d, resolve: h, reject: o } = P();
167
+ const { promise: d, resolve: h, reject: o } = I();
169
168
  try {
170
169
  const l = new XMLHttpRequest();
171
170
  l.open("POST", r, !0), l.setRequestHeader("Content-Type", "application/json"), l.send(s), l.onload = () => {
@@ -186,10 +185,10 @@ class m extends (S = I) {
186
185
  this._timer !== null && (clearInterval(this._timer), this._timer = null), this._usages.length > 0 && this.sendBeacon();
187
186
  }
188
187
  }
189
- f = T(S);
190
- m = M(f, 0, "PluginAnalytics", E, m);
191
- C(f, 1, m);
188
+ _ = T(S);
189
+ m = M(_, 0, "PluginAnalytics", E, m);
190
+ C(_, 1, m);
192
191
  export {
193
192
  m as PluginAnalytics
194
193
  };
195
- //# sourceMappingURL=index-B3FUDhxl.js.map
194
+ //# sourceMappingURL=index-BQ-cHWkJ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-B3FUDhxl.js","sources":["../src/plugins/analytics/index.tsx"],"sourcesContent":["import { Endpoints } from '@/constants/endpoints.js'\nimport { Inject, InPageEdit, Schema } from '@/InPageEdit'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n analytics: PluginAnalytics\n }\n}\n\nexport interface IPEBeaconPayload {\n siteApi: string\n siteName?: string\n userId: number\n userName: string\n version?: string\n usages: IPEBeaconUsage[]\n}\n\nexport interface IPEBeaconUsage {\n ts: number\n feature: string\n subtype?: string\n page?: string\n}\n\n@Inject(['wiki', 'preferences'])\nexport class PluginAnalytics extends BasePlugin {\n private _usages: IPEBeaconUsage[] = []\n private _timer: ReturnType<typeof setInterval> | null = null\n private readonly MAX_QUEUE_SIZE = 50\n private readonly INTERVAL_MS = 60 * 1000 // 1分钟\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'analytics')\n this._setupTimer()\n this._registerUnloadHandler()\n this._showConfirmNotify()\n this._initPluginListeners()\n ctx.set('analytics', this)\n }\n\n protected start(): Promise<void> | void {\n const ctx = this.ctx\n ctx.preferences.registerCustomConfig(\n 'analytics',\n Schema.object({\n 'analytics._intro': Schema.const(\n <section>\n <h3>InPageEdit Analytics</h3>\n <p>\n InPageEdit Analytics is the companion analytics platform for the InPageEdit NEXT\n project. By collecting and displaying usage data from around the world, it helps\n developers and the community better understand how the tool is used, optimize feature\n design, and enhance user experience.\n </p>\n <h4>What data will be collected?</h4>\n <ol style={{ listStyle: 'number', paddingLeft: '1em' }}>\n <li>\n <strong>Usage data</strong>: When and which features you use, what pages you edit,\n etc.\n </li>\n <li>\n <strong>User information</strong>: Your user name and user ID.\n </li>\n <li>\n <strong>Site information</strong>: This wiki's url and site name.\n </li>\n </ol>\n <p>\n <strong>NO sensitive data will be collected.</strong>\n </p>\n <div style={{ display: 'grid', gap: '0.5rem' }}>\n <a href={this.analyticsDashUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n <button className=\"btn\" style={{ width: '100%' }}>\n Analytics Platform\n </button>\n </a>\n <a\n href={`${this.analyticsDashUrl}/_redirect/user?${new URLSearchParams({\n siteApi: this.ctx.wiki.getSciprtUrl('api'),\n mwUserId: this.ctx.wiki.userInfo.id.toString(),\n }).toString()}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <button className=\"btn\" style={{ width: '100%' }}>\n View My Data\n </button>\n </a>\n </div>\n </section>\n ).role('raw-html'),\n 'analytics.enabled': Schema.boolean()\n .description('Share my usage data with the community.')\n .default(false),\n }).description('Analytics settings'),\n 'general'\n )\n }\n\n private get analyticsDashUrl() {\n return import.meta.env.PROD ? Endpoints.ANALYTICS_DASH_URL : 'http://localhost:20105'\n }\n private get analyticsApiBase() {\n return import.meta.env.PROD ? Endpoints.ANALYTICS_API_BASE : 'http://localhost:20105/api/v6'\n }\n\n private _setupTimer() {\n this._timer = setInterval(() => {\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }, this.INTERVAL_MS)\n }\n\n private _registerUnloadHandler() {\n const handleUnload = () => {\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }\n\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n handleUnload()\n }\n })\n\n window.addEventListener('pagehide', handleUnload)\n window.addEventListener('beforeunload', handleUnload)\n }\n\n private async _showConfirmNotify() {\n this.ctx.inject(['modal', 'storage'], async (ctx) => {\n const key = 'analytics/confirm-shown'\n const shown = await ctx.storage.simpleKV.get(key)\n const enabled = await ctx.preferences.get('analytics.enabled')\n if (shown || enabled) {\n return\n }\n ctx.modal.notify(\n 'confirm',\n {\n title: 'Enable Analytics',\n content: (\n <div>\n <p>Help us improve InPageEdit by sharing your usage data with us.</p>\n <p>What data will be collected?</p>\n <ul style={{ listStyle: 'auto', paddingLeft: '1.5em' }}>\n <li>Usage data: What features you use, what pages you edit, etc.</li>\n <li>User information: Your username, user ID.</li>\n <li>Site information: The wiki you are editing.</li>\n </ul>\n <p>\n <strong>NO sensitive data will be collected.</strong>\n </p>\n </div>\n ),\n okBtn: {\n label: 'Enable',\n },\n cancelBtn: {\n label: 'Disable',\n },\n closeAfter: 0,\n onClose: () => {\n this.ctx.storage.simpleKV.set(key, 1)\n },\n },\n (result) => {\n ctx.preferences.set('analytics.enabled', result)\n if (result) {\n this.addEvent('analytics', 'enabled')\n }\n }\n )\n })\n }\n\n private _initPluginListeners() {\n const ctx = this.ctx\n ctx.on('in-article-links/anchor-clicked', (payload) => {\n this.addEvent('in-article-links', paramCase(payload.action))\n })\n ctx.on('quick-delete/submit', (payload) => {\n this.addEvent('quick-delete', 'submit', payload.wikiPage.title)\n })\n ctx.on('quick-diff/loaded', (payload) => {\n this.addEvent('quick-diff', 'loaded', payload.compare.fromtitle)\n })\n ctx.on('quick-redirect/submit', (payload) => {\n this.addEvent('quick-redirect', 'submit', payload.payload.to || undefined)\n })\n ctx.on('quick-preview/loaded', (payload) => {\n this.addEvent('quick-preview', 'loaded', payload.wikiPage.title)\n })\n ctx.on('quick-edit/wiki-page', (payload) => {\n this.addEvent('quick-edit', undefined, payload.wikiPage.title)\n })\n ctx.on('quick-edit/submit', (payload) => {\n this.addEvent('quick-edit', 'submit', payload.wikiPage.title)\n })\n ctx.on('quick-move/submit', (payload) => {\n this.addEvent('quick-move', 'submit')\n })\n ctx.on('toolbox/button-clicked', (payload) => {\n this.addEvent('toolbox', `button-clicked#${payload.id || 'unknown'}`)\n })\n }\n\n public addEvent(feature: string, subtype?: string, page?: string) {\n const usage: IPEBeaconUsage = {\n ts: Date.now(),\n feature,\n subtype,\n page,\n }\n this._usages.push(usage)\n\n // 如果usages数组超过50个,立即发送\n if (this._usages.length >= this.MAX_QUEUE_SIZE) {\n this.sendBeacon()\n }\n\n return this\n }\n\n private async sendBeacon() {\n if (this._usages.length === 0) {\n return true\n }\n\n const enabled = await this.ctx.preferences.get<boolean>('analytics.enabled', false)\n if (!enabled) {\n this.logger.debug('Analytics disabled, skipping')\n return true\n }\n\n const usages = this._usages.splice(0, this._usages.length)\n const payload: IPEBeaconPayload = {\n siteApi: this.ctx.wiki.getSciprtUrl('api'),\n siteName: this.ctx.wiki.siteInfo.general.sitename,\n userId: this.ctx.wiki.userInfo.id,\n userName: this.ctx.wiki.userInfo.name,\n version: this.ctx.version.split('-')[0],\n usages,\n }\n const body = JSON.stringify(payload)\n\n const endpoint = `${this.analyticsApiBase}/submit`\n\n const beaconOK = navigator?.sendBeacon?.(endpoint, body)\n if (beaconOK) {\n this.logger.debug('Beacon sent successfully', payload)\n return true\n } else {\n this.logger.debug('Beacon failed, sending via XMLHttpRequest')\n const { promise, resolve, reject } = promiseWithResolvers<boolean>()\n try {\n const xhr = new XMLHttpRequest()\n xhr.open('POST', endpoint, true)\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.send(body)\n xhr.onload = () => {\n this.logger.debug('Beacon sent successfully via XMLHttpRequest', payload)\n resolve(xhr.status >= 200 && xhr.status < 300)\n }\n xhr.onerror = () => {\n reject(new Error('Failed to send beacon'))\n }\n } catch (error) {\n reject(error)\n }\n return promise\n }\n }\n\n /**\n * 清理资源\n */\n protected stop() {\n if (this._timer !== null) {\n clearInterval(this._timer)\n this._timer = null\n }\n // 在销毁前发送剩余的数据\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }\n}\n"],"names":["_PluginAnalytics_decorators","_init","_a","Inject","PluginAnalytics","BasePlugin","ctx","Schema","jsx","jsxs","Endpoints","handleUnload","key","shown","enabled","result","payload","paramCase","feature","subtype","page","usage","usages","body","endpoint","promise","resolve","reject","promiseWithResolvers","xhr","error","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
1
+ {"version":3,"file":"index-BQ-cHWkJ.js","sources":["../src/plugins/analytics/index.tsx"],"sourcesContent":["import { Endpoints } from '@/constants/endpoints.js'\nimport { Inject, InPageEdit, Schema } from '@/InPageEdit'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n analytics: PluginAnalytics\n }\n}\n\nexport interface IPEBeaconPayload {\n siteApi: string\n siteName?: string\n userId: number\n userName: string\n version?: string\n usages: IPEBeaconUsage[]\n}\n\nexport interface IPEBeaconUsage {\n ts: number\n feature: string\n subtype?: string\n page?: string\n}\n\n@Inject(['wiki', 'preferences'])\nexport class PluginAnalytics extends BasePlugin {\n private _usages: IPEBeaconUsage[] = []\n private _timer: ReturnType<typeof setInterval> | null = null\n private readonly MAX_QUEUE_SIZE = 50\n private readonly INTERVAL_MS = 60 * 1000 // 1分钟\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'analytics')\n this._setupTimer()\n this._registerUnloadHandler()\n this._showConfirmNotify()\n this._initPluginListeners()\n ctx.set('analytics', this)\n }\n\n protected start(): Promise<void> | void {\n const ctx = this.ctx\n ctx.preferences.registerCustomConfig(\n 'analytics',\n Schema.object({\n 'analytics._intro': Schema.const(\n <section>\n <h3>InPageEdit Analytics</h3>\n <p>\n InPageEdit Analytics is the companion analytics platform for the InPageEdit NEXT\n project. By collecting and displaying usage data from around the world, it helps\n developers and the community better understand how the tool is used, optimize feature\n design, and enhance user experience.\n </p>\n <h4>What data will be collected?</h4>\n <ol style={{ listStyle: 'number', paddingLeft: '1em' }}>\n <li>\n <strong>Usage data</strong>: When and which features you use, what pages you edit,\n etc.\n </li>\n <li>\n <strong>User information</strong>: Your user name and user ID.\n </li>\n <li>\n <strong>Site information</strong>: This wiki's url and site name.\n </li>\n </ol>\n <p>\n <strong>NO sensitive data will be collected.</strong>\n </p>\n <div style={{ display: 'grid', gap: '0.5rem' }}>\n <a href={this.analyticsDashUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n <button className=\"btn\" style={{ width: '100%' }}>\n Analytics Platform\n </button>\n </a>\n <a\n href={`${this.analyticsDashUrl}/_redirect/user?${new URLSearchParams({\n siteApi: this.ctx.wiki.getSciprtUrl('api'),\n mwUserId: this.ctx.wiki.userInfo.id.toString(),\n }).toString()}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <button className=\"btn\" style={{ width: '100%' }}>\n View My Data\n </button>\n </a>\n </div>\n </section>\n ).role('raw-html'),\n 'analytics.enabled': Schema.boolean()\n .description('Share my usage data with the community.')\n .default(false),\n }).description('Analytics settings'),\n 'general'\n )\n }\n\n private get analyticsDashUrl() {\n return import.meta.env.PROD ? Endpoints.ANALYTICS_DASH_URL : 'http://localhost:20105'\n }\n private get analyticsApiBase() {\n return import.meta.env.PROD ? Endpoints.ANALYTICS_API_BASE : 'http://localhost:20105/api/v6'\n }\n\n private _setupTimer() {\n this._timer = setInterval(() => {\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }, this.INTERVAL_MS)\n }\n\n private _registerUnloadHandler() {\n const handleUnload = () => {\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }\n\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n handleUnload()\n }\n })\n\n window.addEventListener('pagehide', handleUnload)\n window.addEventListener('beforeunload', handleUnload)\n }\n\n private async _showConfirmNotify() {\n this.ctx.inject(['modal', 'storage'], async (ctx) => {\n const key = 'analytics/confirm-shown'\n const shown = await ctx.storage.simpleKV.get(key)\n const enabled = await ctx.preferences.get('analytics.enabled')\n if (shown || enabled) {\n return\n }\n ctx.modal.notify(\n 'confirm',\n {\n title: 'Enable Analytics',\n content: (\n <div>\n <p>Help us improve InPageEdit by sharing your usage data with us.</p>\n <p>What data will be collected?</p>\n <ul style={{ listStyle: 'auto', paddingLeft: '1.5em' }}>\n <li>Usage data: What features you use, what pages you edit, etc.</li>\n <li>User information: Your username, user ID.</li>\n <li>Site information: The wiki you are editing.</li>\n </ul>\n <p>\n <strong>NO sensitive data will be collected.</strong>\n </p>\n </div>\n ),\n okBtn: {\n label: 'Enable',\n },\n cancelBtn: {\n label: 'Disable',\n },\n closeAfter: 0,\n onClose: () => {\n this.ctx.storage.simpleKV.set(key, 1)\n },\n },\n (result) => {\n ctx.preferences.set('analytics.enabled', result)\n if (result) {\n this.addEvent('analytics', 'enabled')\n }\n }\n )\n })\n }\n\n private _initPluginListeners() {\n const ctx = this.ctx\n ctx.on('in-article-links/anchor-clicked', (payload) => {\n this.addEvent('in-article-links', paramCase(payload.action))\n })\n ctx.on('quick-diff/loaded', (payload) => {\n this.addEvent('quick-diff', 'loaded', payload.compare.fromtitle)\n })\n ctx.on('quick-redirect/submit', (payload) => {\n this.addEvent('quick-redirect', 'submit', payload.payload.to || undefined)\n })\n ctx.on('quick-preview/loaded', (payload) => {\n this.addEvent('quick-preview', 'loaded', payload.wikiPage.title)\n })\n ctx.on('quick-edit/wiki-page', (payload) => {\n this.addEvent('quick-edit', undefined, payload.wikiPage.title)\n })\n ctx.on('quick-edit/submit', (payload) => {\n this.addEvent('quick-edit', 'submit', payload.wikiPage.title)\n })\n ctx.on('quick-move/submit', (payload) => {\n this.addEvent('quick-move', 'submit')\n })\n ctx.on('toolbox/button-clicked', (payload) => {\n this.addEvent('toolbox', `button-clicked#${payload.id || 'unknown'}`)\n })\n }\n\n public addEvent(feature: string, subtype?: string, page?: string) {\n const usage: IPEBeaconUsage = {\n ts: Date.now(),\n feature,\n subtype,\n page,\n }\n this._usages.push(usage)\n\n // 如果usages数组超过50个,立即发送\n if (this._usages.length >= this.MAX_QUEUE_SIZE) {\n this.sendBeacon()\n }\n\n return this\n }\n\n private async sendBeacon() {\n if (this._usages.length === 0) {\n return true\n }\n\n const enabled = await this.ctx.preferences.get<boolean>('analytics.enabled', false)\n if (!enabled) {\n this.logger.debug('Analytics disabled, skipping')\n return true\n }\n\n const usages = this._usages.splice(0, this._usages.length)\n const payload: IPEBeaconPayload = {\n siteApi: this.ctx.wiki.getSciprtUrl('api'),\n siteName: this.ctx.wiki.siteInfo.general.sitename,\n userId: this.ctx.wiki.userInfo.id,\n userName: this.ctx.wiki.userInfo.name,\n version: this.ctx.version.split('-')[0],\n usages,\n }\n const body = JSON.stringify(payload)\n\n const endpoint = `${this.analyticsApiBase}/submit`\n\n const beaconOK = navigator?.sendBeacon?.(endpoint, body)\n if (beaconOK) {\n this.logger.debug('Beacon sent successfully', payload)\n return true\n } else {\n this.logger.debug('Beacon failed, sending via XMLHttpRequest')\n const { promise, resolve, reject } = promiseWithResolvers<boolean>()\n try {\n const xhr = new XMLHttpRequest()\n xhr.open('POST', endpoint, true)\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.send(body)\n xhr.onload = () => {\n this.logger.debug('Beacon sent successfully via XMLHttpRequest', payload)\n resolve(xhr.status >= 200 && xhr.status < 300)\n }\n xhr.onerror = () => {\n reject(new Error('Failed to send beacon'))\n }\n } catch (error) {\n reject(error)\n }\n return promise\n }\n }\n\n /**\n * 清理资源\n */\n protected stop() {\n if (this._timer !== null) {\n clearInterval(this._timer)\n this._timer = null\n }\n // 在销毁前发送剩余的数据\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }\n}\n"],"names":["_PluginAnalytics_decorators","_init","_a","Inject","PluginAnalytics","BasePlugin","ctx","Schema","jsx","jsxs","Endpoints","handleUnload","key","shown","enabled","result","payload","paramCase","feature","subtype","page","usage","usages","body","endpoint","promise","resolve","reject","promiseWithResolvers","xhr","error","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
@@ -1,59 +1,60 @@
1
1
  import { j as R } from "./index-CM_6yF2v.js";
2
- import { S as i, B as T, E as C, I as j } from "./index-DgQNTfPR.js";
2
+ import { S as s, E as T, I as C } from "./endpoints-DgyuoRZd.js";
3
+ import { B as j } from "./BasePlugin-Bf2UuIHF.js";
3
4
  import { c as L, d as O } from "./vueHooks-l04s8cIl.js";
4
5
  const F = 1;
5
6
  var m;
6
7
  ((n) => {
7
- n.PackageLoader = new i(
8
- i.object({
9
- kind: i.union(["autoload", "module", "umd", "styles"]).required().default("autoload"),
10
- entry: i.string(),
11
- styles: i.array(i.string()),
12
- main_export: i.string()
8
+ n.PackageLoader = new s(
9
+ s.object({
10
+ kind: s.union(["autoload", "module", "umd", "styles"]).required().default("autoload"),
11
+ entry: s.string(),
12
+ styles: s.array(s.string()),
13
+ main_export: s.string()
13
14
  })
14
- ), n.Package = new i(
15
- i.object({
16
- id: i.string().required(),
17
- name: i.string().required(),
18
- version: i.string().required(),
19
- description: i.string(),
20
- author: i.string(),
21
- license: i.string(),
15
+ ), n.Package = new s(
16
+ s.object({
17
+ id: s.string().required(),
18
+ name: s.string().required(),
19
+ version: s.string().required(),
20
+ description: s.string(),
21
+ author: s.string(),
22
+ license: s.string(),
22
23
  loader: n.PackageLoader.required()
23
24
  })
24
- ), n.RegistryMaintainer = new i(
25
- i.object({
26
- name: i.string().required(),
27
- email: i.string()
25
+ ), n.RegistryMaintainer = new s(
26
+ s.object({
27
+ name: s.string().required(),
28
+ email: s.string()
28
29
  })
29
- ), n.RegistryRepository = new i(
30
- i.object({
31
- type: i.union(["git"]).required().default("git"),
32
- url: i.string().required()
30
+ ), n.RegistryRepository = new s(
31
+ s.object({
32
+ type: s.union(["git"]).required().default("git"),
33
+ url: s.string().required()
33
34
  })
34
- ), n.Registry = new i(
35
- i.object({
36
- manifest_version: i.number().min(F).required(),
37
- name: i.string().required(),
38
- base_url: i.string().required(),
39
- homepage: i.string(),
40
- maintainers: i.array(n.RegistryMaintainer),
35
+ ), n.Registry = new s(
36
+ s.object({
37
+ manifest_version: s.number().min(F).required(),
38
+ name: s.string().required(),
39
+ base_url: s.string().required(),
40
+ homepage: s.string(),
41
+ maintainers: s.array(n.RegistryMaintainer),
41
42
  repository: n.RegistryRepository,
42
- packages: i.array(n.Package).required()
43
+ packages: s.array(n.Package).required()
43
44
  })
44
45
  );
45
46
  })(m || (m = {}));
46
47
  var G = Object.create, x = Object.defineProperty, B = Object.getOwnPropertyDescriptor, S = (n, e) => (e = Symbol[n]) ? e : Symbol.for("Symbol." + n), b = (n) => {
47
48
  throw TypeError(n);
48
- }, M = (n, e, t) => e in n ? x(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, q = (n, e) => x(n, "name", { value: e, configurable: !0 }), N = (n) => [, , , G(n?.[S("metadata")] ?? null)], D = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], $ = (n) => n !== void 0 && typeof n != "function" ? b("Function expected") : n, U = (n, e, t, r, s) => ({ kind: D[n], name: e, metadata: r, addInitializer: (a) => t._ ? b("Already initialized") : s.push($(a || null)) }), Y = (n, e) => M(e, S("metadata"), n[3]), z = (n, e, t, r) => {
49
- for (var s = 0, a = n[e >> 1], l = a && a.length; s < l; s++) a[s].call(t);
49
+ }, M = (n, e, t) => e in n ? x(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, q = (n, e) => x(n, "name", { value: e, configurable: !0 }), N = (n) => [, , , G(n?.[S("metadata")] ?? null)], D = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], $ = (n) => n !== void 0 && typeof n != "function" ? b("Function expected") : n, U = (n, e, t, r, i) => ({ kind: D[n], name: e, metadata: r, addInitializer: (a) => t._ ? b("Already initialized") : i.push($(a || null)) }), Y = (n, e) => M(e, S("metadata"), n[3]), z = (n, e, t, r) => {
50
+ for (var i = 0, a = n[e >> 1], l = a && a.length; i < l; i++) a[i].call(t);
50
51
  return r;
51
- }, Q = (n, e, t, r, s, a) => {
52
- var l, f, h, g = e & 7, p = !1, c = 0, y = n[c] || (n[c] = []), d = g && (s = s.prototype, g < 5 && (g > 3 || !p) && B(s, t));
53
- q(s, t);
52
+ }, Q = (n, e, t, r, i, a) => {
53
+ var l, f, h, g = e & 7, p = !1, c = 0, y = n[c] || (n[c] = []), d = g && (i = i.prototype, g < 5 && (g > 3 || !p) && B(i, t));
54
+ q(i, t);
54
55
  for (var o = r.length - 1; o >= 0; o--)
55
- h = U(g, t, f = {}, n[3], y), l = (0, r[o])(s, h), f._ = 1, $(l) && (s = l);
56
- return Y(n, s), d && x(s, t, d), p ? g ^ 4 ? a : d : s;
56
+ h = U(g, t, f = {}, n[3], y), l = (0, r[o])(i, h), f._ = 1, $(l) && (i = l);
57
+ return Y(n, i), d && x(i, t, d), p ? g ^ 4 ? a : d : i;
57
58
  }, k, I, A;
58
59
  const P = (n) => {
59
60
  if (!n) return null;
@@ -69,17 +70,17 @@ const P = (n) => {
69
70
  const l = r(e);
70
71
  return new URL(n, l).href;
71
72
  }
72
- const s = (() => {
73
+ const i = (() => {
73
74
  try {
74
75
  return new URL(t).href;
75
76
  } catch {
76
77
  return new URL(t, location.origin).href;
77
78
  }
78
- })(), a = new URL(r(e), s).href;
79
+ })(), a = new URL(r(e), i).href;
79
80
  return new URL(n, a).href;
80
81
  };
81
- k = [j(["storage", "preferences", "resourceLoader"])];
82
- let w = class v extends (A = T) {
82
+ k = [C(["storage", "preferences", "resourceLoader"])];
83
+ let w = class v extends (A = j) {
83
84
  constructor(e) {
84
85
  super(e, {}, "plugin-store"), this.ctx = e, this.regInfoDB = void 0, this._installedPlugins = /* @__PURE__ */ new Map(), this._onlineRegistryQueries = /* @__PURE__ */ new Map(), e.set("store", this), this.regInfoDB = e.storage.createDatabase(
85
86
  v.REGISTRY_INFO_STORAGE_NAME,
@@ -110,7 +111,7 @@ let w = class v extends (A = T) {
110
111
  this.install(t.registry, t.id, t.source);
111
112
  }
112
113
  async _createManagementApp() {
113
- const e = await this.ctx.withInject(["store"]), t = O(() => import("./PluginStoreApp-Bnvyl-Oc.js"));
114
+ const e = await this.ctx.withInject(["store"]), t = O(() => import("./PluginStoreApp-CpOLArL7.js"));
114
115
  return L(e, t);
115
116
  }
116
117
  async _injectPreferenceUI() {
@@ -122,23 +123,23 @@ let w = class v extends (A = T) {
122
123
  index: 90,
123
124
  autoGenerateForm: !1,
124
125
  customRenderer: async ({ onUnmount: t }) => {
125
- const r = /* @__PURE__ */ R("div", { id: "ipe-plugin-store-preferences-vue" }), s = await this._createManagementApp();
126
- return s.mount(r), t(() => {
127
- s.unmount(), this.ctx.logger.debug("Plugin Store preferences app unmounted");
126
+ const r = /* @__PURE__ */ R("div", { id: "ipe-plugin-store-preferences-vue" }), i = await this._createManagementApp();
127
+ return i.mount(r), t(() => {
128
+ i.unmount(), this.ctx.logger.debug("Plugin Store preferences app unmounted");
128
129
  }), /* @__PURE__ */ R("section", { children: r });
129
130
  }
130
131
  }), e.preferences.registerCustomConfig(
131
132
  "plugin-store",
132
- i.object({
133
- "pluginStore.registries": i.array(i.string()).default([
134
- C.PLUGIN_REGISTRY_URL
133
+ s.object({
134
+ "pluginStore.registries": s.array(s.string()).default([
135
+ T.PLUGIN_REGISTRY_URL
135
136
  ]).description("Registry URLs").hidden(),
136
- "pluginStore.cdnForNpm": i.string().description("CDN to install packages from npm").default('https://cdn.jsdelivr.net/npm/{{ package }}{{ version ? "@" + version : "" }}').hidden(),
137
- "pluginStore.plugins": i.array(
138
- i.object({
139
- source: i.union(["online_manifest", "npm"]).default("online_manifest"),
140
- registry: i.string().required(),
141
- id: i.string().required()
137
+ "pluginStore.cdnForNpm": s.string().description("CDN to install packages from npm").default('https://cdn.jsdelivr.net/npm/{{ package }}{{ version ? "@" + version : "" }}').hidden(),
138
+ "pluginStore.plugins": s.array(
139
+ s.object({
140
+ source: s.union(["online_manifest", "npm"]).default("online_manifest"),
141
+ registry: s.string().required(),
142
+ id: s.string().required()
142
143
  })
143
144
  ).description("Installed plugins").default([]).hidden()
144
145
  }),
@@ -157,13 +158,13 @@ let w = class v extends (A = T) {
157
158
  }), e;
158
159
  }
159
160
  async install(e, t, r = "online_manifest") {
160
- const s = await this.getRegistryInfo(e, r);
161
- if (!s)
161
+ const i = await this.getRegistryInfo(e, r);
162
+ if (!i)
162
163
  return this.ctx.logger.warn(`Registry ${e} not found`), null;
163
164
  const a = `${e}#${t}`;
164
165
  if (this._installedPlugins.has(a))
165
166
  return await this._installedPlugins.get(a) ?? null;
166
- const l = this._installOneByRegistryInfo(e, s, t);
167
+ const l = this._installOneByRegistryInfo(e, i, t);
167
168
  return this._installedPlugins.set(a, l), await l;
168
169
  }
169
170
  async uninstall(e, t) {
@@ -171,8 +172,8 @@ let w = class v extends (A = T) {
171
172
  if (r === void 0)
172
173
  return !0;
173
174
  this._installedPlugins.delete(`${e}#${t}`);
174
- const s = await r;
175
- return s ? s.dispose?.() ?? !0 : !0;
175
+ const i = await r;
176
+ return i ? i.dispose?.() ?? !0 : !0;
176
177
  }
177
178
  async addToPreferences(e, t) {
178
179
  let r = await this.ctx.preferences.get("pluginStore.plugins") || [];
@@ -180,7 +181,7 @@ let w = class v extends (A = T) {
180
181
  }
181
182
  async removeFromPreferences(e, t) {
182
183
  let r = await this.ctx.preferences.get("pluginStore.plugins") || [];
183
- return r = r.filter((s) => s.registry !== e || s.id !== t), await this.ctx.preferences.set("pluginStore.plugins", r), !0;
184
+ return r = r.filter((i) => i.registry !== e || i.id !== t), await this.ctx.preferences.set("pluginStore.plugins", r), !0;
184
185
  }
185
186
  async installAndSetPreference(e, t) {
186
187
  return await this.addToPreferences(e, t), this.install(e, t);
@@ -190,7 +191,7 @@ let w = class v extends (A = T) {
190
191
  }
191
192
  // 3) 增加 registryUrl 参数
192
193
  async _installOneByRegistryInfo(e, t, r) {
193
- const s = t.base_url, a = t.packages.find((o) => o.id === r);
194
+ const i = t.base_url, a = t.packages.find((o) => o.id === r);
194
195
  if (!a)
195
196
  return this.ctx.logger.warn(`Package ${r} not found in registry ${e}`), null;
196
197
  const l = a.loader, { kind: f, entry: h = "index.js", styles: g = [], main_export: p = null } = l;
@@ -199,10 +200,10 @@ let w = class v extends (A = T) {
199
200
  if (!h)
200
201
  return this.ctx.logger.warn(`Entry url missing for ${r}`, l), null;
201
202
  try {
202
- c = E(h, s, e);
203
+ c = E(h, i, e);
203
204
  } catch (o) {
204
205
  return this.ctx.logger.warn(
205
- `Failed to resolve entry "${h}" with base "${s}" and registry "${e}"`,
206
+ `Failed to resolve entry "${h}" with base "${i}" and registry "${e}"`,
206
207
  o
207
208
  ), null;
208
209
  }
@@ -255,7 +256,7 @@ let w = class v extends (A = T) {
255
256
  if (g && g.length > 0) {
256
257
  let o = [];
257
258
  try {
258
- o = g.map((u) => E(u, s, e)).filter(Boolean);
259
+ o = g.map((u) => E(u, i, e)).filter(Boolean);
259
260
  } catch (u) {
260
261
  this.ctx.logger.warn(`Failed to resolve styles for ${r}`, g, u);
261
262
  }
@@ -293,15 +294,15 @@ let w = class v extends (A = T) {
293
294
  } catch (a) {
294
295
  this.ctx.logger.warn("Failed to fetch registry info", a);
295
296
  }
296
- const s = await this.getRegistryCache(e);
297
- if (!s)
297
+ const i = await this.getRegistryCache(e);
298
+ if (!i)
298
299
  throw new Error(`Failed to fetch registry info: ${e}`);
299
- return s;
300
+ return i;
300
301
  }
301
302
  async _fetchOnlineRegistryInfo(e, t = !1) {
302
303
  if (!t && this._onlineRegistryQueries.has(e))
303
304
  return await this._onlineRegistryQueries.get(e);
304
- const s = (async () => {
305
+ const i = (async () => {
305
306
  const a = {
306
307
  method: "GET"
307
308
  };
@@ -309,7 +310,7 @@ let w = class v extends (A = T) {
309
310
  const f = await (await fetch(e, a)).json();
310
311
  return this.validateRegistry(f);
311
312
  })();
312
- return this._onlineRegistryQueries.set(e, s), await s;
313
+ return this._onlineRegistryQueries.set(e, i), await i;
313
314
  }
314
315
  async getRegistryCache(e) {
315
316
  const t = await this.regInfoDB.get(e);
@@ -344,18 +345,18 @@ let w = class v extends (A = T) {
344
345
  */
345
346
  async refreshAllRegistryCaches() {
346
347
  const e = await this.ctx.preferences.get("pluginStore.registries") || [], t = await Promise.allSettled(
347
- e.map((s) => this.refreshRegistryCache(s))
348
+ e.map((i) => this.refreshRegistryCache(i))
348
349
  ), r = {};
349
- for (const [s, a] of t.entries())
350
- a.status === "fulfilled" ? r[e[s]] = a.value : r[e[s]] = null;
350
+ for (const [i, a] of t.entries())
351
+ a.status === "fulfilled" ? r[e[i]] = a.value : r[e[i]] = null;
351
352
  return r;
352
353
  }
353
354
  };
354
355
  I = N(A);
355
356
  w = Q(I, 0, "PluginPluginStore", k, w);
356
357
  z(I, 1, w);
357
- let J = w;
358
+ let K = w;
358
359
  export {
359
- J as PluginPluginStore
360
+ K as PluginPluginStore
360
361
  };
361
- //# sourceMappingURL=index-B3YJdjxo.js.map
362
+ //# sourceMappingURL=index-BwdWyHLe.js.map