@graffiti-garden/wrapper-vue 1.0.3 → 1.0.4

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.
@@ -1,7 +1,7 @@
1
- import { GraffitiSession, GraffitiMediaRequirements, GraffitiMedia } from '@graffiti-garden/api';
1
+ import { GraffitiSession, GraffitiMediaAccept, GraffitiMedia } from '@graffiti-garden/api';
2
2
  type __VLS_Props = {
3
3
  url: string;
4
- requirements: GraffitiMediaRequirements;
4
+ accept: GraffitiMediaAccept;
5
5
  session?: GraffitiSession | null;
6
6
  };
7
7
  declare function __VLS_template(): {
@@ -1 +1 @@
1
- {"version":3,"file":"GetMedia.vue.d.ts","sourceRoot":"","sources":["../../../src/components/GetMedia.vue"],"names":[],"mappings":"AA8EA,OAAO,KAAK,EACR,eAAe,EACf,yBAAyB,EACzB,aAAa,EAChB,MAAM,sBAAsB,CAAC;AAG9B,KAAK,WAAW,GAAG;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,yBAAyB,CAAC;IACxC,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACpC,CAAC;AAwBF,iBAAS,cAAc;WAsET,OAAO,IAA6B;;wBA1F9B;YACZ,KAAK,EAAE,CAAC,aAAa,GAAG;gBAAE,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;YAChE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;SAC7B,GAAG,GAAG;;wBAHS;YACZ,KAAK,EAAE,CAAC,aAAa,GAAG;gBAAE,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;YAChE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;SAC7B,GAAG,GAAG;;;;EA4FV;AAWD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe,kSAMnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAQpG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"GetMedia.vue.d.ts","sourceRoot":"","sources":["../../../src/components/GetMedia.vue"],"names":[],"mappings":"AA8EA,OAAO,KAAK,EACR,eAAe,EACf,mBAAmB,EACnB,aAAa,EAChB,MAAM,sBAAsB,CAAC;AAG9B,KAAK,WAAW,GAAG;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACpC,CAAC;AAwBF,iBAAS,cAAc;WAsET,OAAO,IAA6B;;wBA1F9B;YACZ,KAAK,EAAE,CAAC,aAAa,GAAG;gBAAE,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;YAChE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;SAC7B,GAAG,GAAG;;wBAHS;YACZ,KAAK,EAAE,CAAC,aAAa,GAAG;gBAAE,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;YAChE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;SAC7B,GAAG,GAAG;;;;EA4FV;AAWD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe,kSAMnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAQpG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
@@ -1,4 +1,4 @@
1
- import { GraffitiMedia, GraffitiMediaRequirements, GraffitiSession } from '@graffiti-garden/api';
1
+ import { GraffitiMedia, GraffitiMediaAccept, GraffitiSession } from '@graffiti-garden/api';
2
2
  import { MaybeRefOrGetter, Ref } from 'vue';
3
3
  /**
4
4
  * The [Graffiti.getMedia](https://api.graffiti.garden/classes/Graffiti.html#getMedia)
@@ -22,7 +22,7 @@ import { MaybeRefOrGetter, Ref } from 'vue';
22
22
  * the result is `null`. If the media is still being fetched, the result is `undefined`.
23
23
  * - `poll`: A function that can be called to manually check if the media has changed.
24
24
  */
25
- export declare function useGraffitiGetMedia(url: MaybeRefOrGetter<string>, requirements: MaybeRefOrGetter<GraffitiMediaRequirements>, session?: MaybeRefOrGetter<GraffitiSession | undefined | null>): {
25
+ export declare function useGraffitiGetMedia(url: MaybeRefOrGetter<string>, accept: MaybeRefOrGetter<GraffitiMediaAccept>, session?: MaybeRefOrGetter<GraffitiSession | undefined | null>): {
26
26
  media: Ref<(GraffitiMedia & {
27
27
  dataUrl: string;
28
28
  }) | null | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"get-media.d.ts","sourceRoot":"","sources":["../../../src/composables/get-media.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,yBAAyB,EACzB,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC7B,YAAY,EAAE,gBAAgB,CAAC,yBAAyB,CAAC,EACzD,OAAO,CAAC,EAAE,gBAAgB,CAAC,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC,GAC7D;IACD,KAAK,EAAE,GAAG,CAAC,CAAC,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACrE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CA4EA"}
1
+ {"version":3,"file":"get-media.d.ts","sourceRoot":"","sources":["../../../src/composables/get-media.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC7B,MAAM,EAAE,gBAAgB,CAAC,mBAAmB,CAAC,EAC7C,OAAO,CAAC,EAAE,gBAAgB,CAAC,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC,GAC7D;IACD,KAAK,EAAE,GAAG,CAAC,CAAC,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACrE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CA4EA"}
@@ -279,7 +279,7 @@ export declare const GraffitiGet: <Schema extends import('json-schema-to-ts').JS
279
279
  export declare const GraffitiGetMedia: {
280
280
  new (...args: any[]): import('vue').CreateComponentPublicInstanceWithMixins<Readonly<{
281
281
  url: string;
282
- requirements: import('@graffiti-garden/api').GraffitiMediaRequirements;
282
+ accept: import('@graffiti-garden/api').GraffitiMediaAccept;
283
283
  session?: GraffitiSession | null;
284
284
  }> & Readonly<{}>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, import('vue').PublicProps, {}, false, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {}, any, import('vue').ComponentProvideOptions, {
285
285
  P: {};
@@ -290,7 +290,7 @@ export declare const GraffitiGetMedia: {
290
290
  Defaults: {};
291
291
  }, Readonly<{
292
292
  url: string;
293
- requirements: import('@graffiti-garden/api').GraffitiMediaRequirements;
293
+ accept: import('@graffiti-garden/api').GraffitiMediaAccept;
294
294
  session?: GraffitiSession | null;
295
295
  }> & Readonly<{}>, {}, {}, {}, {}, {}>;
296
296
  __isFragment?: never;
@@ -298,7 +298,7 @@ export declare const GraffitiGetMedia: {
298
298
  __isSuspense?: never;
299
299
  } & import('vue').ComponentOptionsBase<Readonly<{
300
300
  url: string;
301
- requirements: import('@graffiti-garden/api').GraffitiMediaRequirements;
301
+ accept: import('@graffiti-garden/api').GraffitiMediaAccept;
302
302
  session?: GraffitiSession | null;
303
303
  }> & Readonly<{}>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, {}, {}, string, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, import('vue').ComponentProvideOptions> & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps & (new () => {
304
304
  $slots: Readonly<{
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),_=require("@graffiti-garden/wrapper-synchronize");var G=class R extends Error{constructor(a){super(a),this.name="GraffitiErrorNotFound",Object.setPrototypeOf(this,R.prototype)}};const E={};function W(t){if(!E.graffitiSession)E.graffitiSession=t;else throw new Error("Graffiti session already set - plugin installed multiple times?")}function q(t){if(!E.graffitiSynchronize)E.graffitiSynchronize=t;else throw new Error("Graffiti synchronize already set - plugin installed multiple times?")}function b(){const t=E.graffitiSynchronize;if(!t)throw new Error("No Graffiti instance provided, did you forget to install the plugin?");return t}function N(){return b()}function x(){const t=E.graffitiSession;if(!t)throw new Error("No Graffiti session provided, did you forget to install the plugin?");return t}function T(t,a,n,i=!1){const l=b(),o=new Map,r=e.ref([]);let s=async()=>{};const m=async()=>s(),u=e.ref(!0);let k,p;e.onScopeDispose(()=>{k?.return(null),p?.return({continue:()=>p,cursor:""})});const y=e.ref(0);function f(c=0){setTimeout(()=>{y.value++},c)}return e.watch(()=>({args:[e.toValue(t),e.toValue(a),e.toValue(n)],refresh:y.value}),({args:c},A,w)=>{o.clear(),r.value=[],u.value=!0;const j=l.synchronizeDiscover(...c);k=j;let h,v=!0;w(()=>{v=!1,j.return(null),h?.return({continue:()=>p,cursor:""})});let g;(async()=>{for await(const d of j){if(!v)break;d.tombstone?o.delete(d.object.url):o.set(d.object.url,d.object),g||(g=new Promise($=>{setTimeout(()=>{v&&(r.value=Array.from(o.values())),g=void 0,$()},50)}))}})();let S=!1,D=()=>l.discover(...c);s=async()=>{if(!(S||!v)){S=!0;try{h=D(c[2])}catch{return f(5e3)}if(v){for(p=h;;){let d;try{d=await h.next()}catch($){return $ instanceof G?f():f(5e3)}if(!v)return;if(d.done){D=d.value.continue;break}else d.value.error&&console.error(d.value.error)}await new Promise(d=>setTimeout(d,0)),g&&await g,v&&(S=!1,u.value=!1,e.toValue(i)&&m())}}},m()},{immediate:!0}),e.watch(()=>e.toValue(i),c=>c&&m()),{objects:r,poll:m,isFirstPoll:u}}function P(t,a){const n=e.ref(void 0);return e.watch(()=>e.toValue(t),async(i,l,o)=>{let r=!0;o(()=>{r=!1}),n.value=void 0;try{const s=await a(i);r&&(n.value=s)}catch(s){if(!r)return;s instanceof G?n.value=null:console.error(s)}},{immediate:!0}),{output:n}}function L(t){return t===void 0?"Loading...":t===null?"Not found":t}function U(t){const a=N(),{output:n}=P(t,a.actorToHandle.bind(a));return{handle:n}}const V=e.defineComponent({__name:"ActorToHandle",props:{actor:{}},setup(t){const a=t,n=e.toRef(a,"actor"),{handle:i}=U(n);return(l,o)=>e.renderSlot(l.$slots,"default",{handle:e.unref(i)},()=>[e.createElementVNode("span",null,e.toDisplayString(e.unref(L)(e.unref(i))),1)])}}),J=["data-url"],K={key:0},Q={key:1},X={key:0},Y={key:1},Z={key:0},ee=["disabled"],te={key:1},oe={key:2},B=e.defineComponent({__name:"ObjectInfo",props:{object:{}},setup(t){const a=N(),n=e.ref(!1);async function i(l,o){n.value=!0,await new Promise(r=>setTimeout(r,0)),confirm("Are you sure you want to delete this object? It cannot be undone.")&&await a.delete(l,o),n.value=!1}return(l,o)=>t.object?(e.openBlock(),e.createElementBlock("article",{key:0,"data-url":t.object.url},[e.createElementVNode("header",null,[o[4]||(o[4]=e.createElementVNode("h2",null,"Graffiti Object",-1)),e.createElementVNode("dl",null,[o[1]||(o[1]=e.createElementVNode("dt",null,"Object URL",-1)),e.createElementVNode("dd",null,[e.createElementVNode("code",null,e.toDisplayString(t.object.url),1)]),o[2]||(o[2]=e.createElementVNode("dt",null,"Actor",-1)),e.createElementVNode("dd",null,[e.createElementVNode("code",null,e.toDisplayString(t.object.actor),1)]),o[3]||(o[3]=e.createElementVNode("dt",null,"Handle",-1)),e.createElementVNode("dd",null,[e.createVNode(V,{actor:t.object.actor},null,8,["actor"])])])]),e.createElementVNode("section",null,[o[5]||(o[5]=e.createElementVNode("h3",null,"Content",-1)),e.createElementVNode("pre",null,e.toDisplayString(t.object.value),1)]),e.createElementVNode("section",null,[o[10]||(o[10]=e.createElementVNode("h3",null,"Allowed Actors",-1)),Array.isArray(t.object.allowed)?t.object.allowed.length===0?(e.openBlock(),e.createElementBlock("p",Q,[...o[7]||(o[7]=[e.createElementVNode("em",null,"Noone",-1)])])):e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("p",K,[...o[6]||(o[6]=[e.createElementVNode("em",null,"Public",-1)])])),e.createElementVNode("ul",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.object.allowed,r=>(e.openBlock(),e.createElementBlock("li",{key:r},[e.createElementVNode("dl",null,[o[8]||(o[8]=e.createElementVNode("dt",null,"Actor",-1)),e.createElementVNode("dd",null,[e.createElementVNode("code",null,e.toDisplayString(r),1)]),o[9]||(o[9]=e.createElementVNode("dt",null,"Handle",-1)),e.createElementVNode("dd",null,[e.createVNode(V,{actor:r},null,8,["actor"])])])]))),128))])]),e.createElementVNode("section",null,[o[12]||(o[12]=e.createElementVNode("h3",null,"Channels",-1)),t.object.channels?.length?(e.openBlock(),e.createElementBlock("ul",X,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.object.channels,r=>(e.openBlock(),e.createElementBlock("li",{key:r},[e.createElementVNode("code",null,e.toDisplayString(r),1)]))),128))])):(e.openBlock(),e.createElementBlock("p",Y,[...o[11]||(o[11]=[e.createElementVNode("em",null,"No channels",-1)])]))]),e.createElementVNode("footer",null,[e.createElementVNode("nav",null,[e.createElementVNode("ul",null,[l.$graffitiSession.value?.actor===t.object.actor?(e.openBlock(),e.createElementBlock("li",Z,[e.createElementVNode("button",{disabled:n.value,onClick:o[0]||(o[0]=r=>i(t.object,l.$graffitiSession.value))},e.toDisplayString(n.value?"Deleting...":"Delete"),9,ee)])):e.createCommentVNode("",!0)])])])],8,J)):t.object===null?(e.openBlock(),e.createElementBlock("article",te,[...o[13]||(o[13]=[e.createElementVNode("header",null,[e.createElementVNode("h2",null,"Graffiti Object")],-1),e.createElementVNode("p",null,[e.createElementVNode("em",null,"Object not found")],-1)])])):(e.openBlock(),e.createElementBlock("article",oe,[...o[14]||(o[14]=[e.createElementVNode("header",null,[e.createElementVNode("h2",null,"Graffiti Object")],-1),e.createElementVNode("p",null,[e.createElementVNode("em",null,"Loading...")],-1)])]))}}),ne={key:0},re={key:1},O=e.defineComponent({__name:"Discover",props:{channels:{},schema:{},session:{},autopoll:{type:Boolean}},setup(t){const a=t,{objects:n,poll:i,isFirstPoll:l}=T(e.toRef(a,"channels"),e.toRef(a,"schema"),e.toRef(a,"session"),e.toRef(a,"autopoll"));return(o,r)=>e.renderSlot(o.$slots,"default",{objects:e.unref(n),poll:e.unref(i),isFirstPoll:e.unref(l)},()=>[e.unref(l)?(e.openBlock(),e.createElementBlock("p",re,[...r[0]||(r[0]=[e.createElementVNode("em",null," Loading... ",-1)])])):(e.openBlock(),e.createElementBlock("ul",ne,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(n),s=>(e.openBlock(),e.createElementBlock("li",{key:s.url},[e.createVNode(B,{object:s},null,8,["object"])]))),128))]))])}});function H(t,a,n){const i=b(),l=e.ref(void 0);let o=async()=>{};const r=async()=>o();let s;return e.onScopeDispose(()=>{s?.return(null)}),e.watch(()=>[e.toValue(t),e.toValue(a),e.toValue(n)],(m,u,k)=>{l.value=void 0;const p=i.synchronizeGet(...m);s=p;let y=!0;k(()=>{y=!1,p.return(null)}),(async()=>{for await(const c of p){if(!y)return;c.tombstone?l.value=null:l.value=c.object}})();let f=!1;o=async()=>{if(!(f||!y)){f=!0;try{await i.get(...m)}catch(c){c instanceof G||console.error(c)}await new Promise(c=>setTimeout(c,0)),f=!1}},r()},{immediate:!0}),{object:l,poll:r}}const C=e.defineComponent({__name:"Get",props:{url:{},schema:{},session:{}},setup(t){const a=t,{object:n,poll:i}=H(e.toRef(a,"url"),e.toRef(a,"schema"),e.toRef(a,"session"));return(l,o)=>e.renderSlot(l.$slots,"default",{object:e.unref(n),poll:e.unref(i)},()=>[e.createVNode(B,{object:e.unref(n)},null,8,["object"])])}});function z(t,a,n){const i=b(),l=e.ref(void 0),o=e.ref(0);let r=null,s=()=>{};function m(){return r||(o.value++,r=new Promise(u=>{s=()=>{r=null,u()}}),r)}return e.watch(()=>({args:[e.toValue(t),e.toValue(a),e.toValue(n)],pollCounter:o.value}),async({args:u},k,p)=>{l.value?.dataUrl&&URL.revokeObjectURL(l.value.dataUrl),l.value=void 0;let y=!0;p(()=>{y=!1});try{const{data:f,actor:c,allowed:A}=await i.getMedia(...u);if(!y)return;const w=URL.createObjectURL(f);l.value={data:f,dataUrl:w,actor:c,allowed:A}}catch(f){if(!y)return;f instanceof G?l.value=null:console.error(f)}finally{s()}},{immediate:!0}),e.onScopeDispose(()=>{s(),l.value?.dataUrl&&URL.revokeObjectURL(l.value.dataUrl)}),{media:l,poll:m}}const le=["src","alt"],ae=["src","alt"],ie=["src","alt"],se=["src","alt"],ce=["data","alt"],ue={key:6},fe={key:7},M=e.defineComponent({__name:"GetMedia",props:{url:{},requirements:{},session:{}},setup(t){const a=t,{media:n,poll:i}=z(e.toRef(a,"url"),e.toRef(a,"requirements"),e.toRef(a,"session"));function l(){n.value&&(window.location.href=n.value.dataUrl)}return(o,r)=>e.renderSlot(o.$slots,"default",{media:e.unref(n),poll:e.unref(i)},()=>[e.unref(n)?.data.type.startsWith("image/")?(e.openBlock(),e.createElementBlock("img",{key:0,src:e.unref(n).dataUrl,alt:`An image by ${e.unref(n).actor}`},null,8,le)):e.unref(n)?.data.type.startsWith("video/")?(e.openBlock(),e.createElementBlock("video",{key:1,controls:"",src:e.unref(n).dataUrl,alt:`A video by ${e.unref(n).actor}`},null,8,ae)):e.unref(n)?.data.type.startsWith("audio/")?(e.openBlock(),e.createElementBlock("audio",{key:2,controls:"",src:e.unref(n).dataUrl,alt:`Audio by ${e.unref(n).actor}`},null,8,ie)):e.unref(n)?.data.type==="text/html"?(e.openBlock(),e.createElementBlock("iframe",{key:3,src:e.unref(n).dataUrl,alt:`HTML by ${e.unref(n).actor}`,sandbox:""},null,8,se)):e.unref(n)?.data.type.startsWith("application/pdf")?(e.openBlock(),e.createElementBlock("object",{key:4,data:e.unref(n).dataUrl,type:"application/pdf",alt:`PDF by ${e.unref(n).actor}`},null,8,ce)):e.unref(n)?(e.openBlock(),e.createElementBlock("button",{key:5,onClick:l},"Download")):e.unref(n)===null?(e.openBlock(),e.createElementBlock("p",ue,[...r[0]||(r[0]=[e.createElementVNode("em",null,"Media not found",-1)])])):(e.openBlock(),e.createElementBlock("p",fe,[...r[1]||(r[1]=[e.createElementVNode("em",null," Loading... ",-1)])]))])}});function F(t){const a=N(),{output:n}=P(t,a.handleToActor.bind(a));return{actor:n}}const I=e.defineComponent({__name:"HandleToActor",props:{handle:{}},setup(t){const a=t,n=e.toRef(a,"handle"),{actor:i}=F(n);return(l,o)=>e.renderSlot(l.$slots,"default",{actor:e.unref(i)},()=>[e.createElementVNode("span",null,e.toDisplayString(e.unref(L)(e.unref(i))),1)])}}),de={install(t,a){const n=a.graffiti,i=new _.GraffitiSynchronize(n),l=e.ref(void 0);i.sessionEvents.addEventListener("initialized",async o=>{const r=o.detail;if(r&&r.error&&console.error(r.error),r&&r.href){const s=t.config.globalProperties.$router;if(s){const m=s.options.history.base,u=new URL(r.href);u.pathname.startsWith(m)&&(u.pathname=u.pathname.slice(m.length)),await s.replace(u.pathname+u.search+u.hash)}}l.value||(l.value=null)}),i.sessionEvents.addEventListener("login",o=>{const r=o.detail;if(r.error){console.error("Error logging in:"),console.error(r.error);return}else l.value=r.session}),i.sessionEvents.addEventListener("logout",o=>{const r=o.detail;r.error?(console.error("Error logging out:"),console.error(r.error)):l.value=null}),q(i),W(l),t.component("GraffitiDiscover",O),t.component("GraffitiGet",C),t.component("GraffitiGetMedia",M),t.component("GraffitiActorToHandle",V),t.component("GraffitiHandleToActor",I),t.component("GraffitiObjectInfo",B),t.config.globalProperties.$graffiti=i,t.config.globalProperties.$graffitiSession=l}},me=O,pe=C,ye=M,ve=V,Ee=I,ke=B;exports.GraffitiActorToHandle=ve;exports.GraffitiDiscover=me;exports.GraffitiGet=pe;exports.GraffitiGetMedia=ye;exports.GraffitiHandleToActor=Ee;exports.GraffitiObjectInfo=ke;exports.GraffitiPlugin=de;exports.useGraffiti=N;exports.useGraffitiActorToHandle=U;exports.useGraffitiDiscover=T;exports.useGraffitiGet=H;exports.useGraffitiGetMedia=z;exports.useGraffitiHandleToActor=F;exports.useGraffitiSession=x;exports.useGraffitiSynchronize=b;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),_=require("@graffiti-garden/wrapper-synchronize");var G=class R extends Error{constructor(a){super(a),this.name="GraffitiErrorNotFound",Object.setPrototypeOf(this,R.prototype)}};const E={};function W(t){if(!E.graffitiSession)E.graffitiSession=t;else throw new Error("Graffiti session already set - plugin installed multiple times?")}function x(t){if(!E.graffitiSynchronize)E.graffitiSynchronize=t;else throw new Error("Graffiti synchronize already set - plugin installed multiple times?")}function b(){const t=E.graffitiSynchronize;if(!t)throw new Error("No Graffiti instance provided, did you forget to install the plugin?");return t}function N(){return b()}function q(){const t=E.graffitiSession;if(!t)throw new Error("No Graffiti session provided, did you forget to install the plugin?");return t}function T(t,a,n,i=!1){const l=b(),o=new Map,r=e.ref([]);let s=async()=>{};const m=async()=>s(),u=e.ref(!0);let k,p;e.onScopeDispose(()=>{k?.return(null),p?.return({continue:()=>p,cursor:""})});const y=e.ref(0);function f(c=0){setTimeout(()=>{y.value++},c)}return e.watch(()=>({args:[e.toValue(t),e.toValue(a),e.toValue(n)],refresh:y.value}),({args:c},A,w)=>{o.clear(),r.value=[],u.value=!0;const j=l.synchronizeDiscover(...c);k=j;let h,v=!0;w(()=>{v=!1,j.return(null),h?.return({continue:()=>p,cursor:""})});let g;(async()=>{for await(const d of j){if(!v)break;d.tombstone?o.delete(d.object.url):o.set(d.object.url,d.object),g||(g=new Promise($=>{setTimeout(()=>{v&&(r.value=Array.from(o.values())),g=void 0,$()},50)}))}})();let S=!1,D=()=>l.discover(...c);s=async()=>{if(!(S||!v)){S=!0;try{h=D(c[2])}catch{return f(5e3)}if(v){for(p=h;;){let d;try{d=await h.next()}catch($){return $ instanceof G?f():f(5e3)}if(!v)return;if(d.done){D=d.value.continue;break}else d.value.error&&console.error(d.value.error)}await new Promise(d=>setTimeout(d,0)),g&&await g,v&&(S=!1,u.value=!1,e.toValue(i)&&m())}}},m()},{immediate:!0}),e.watch(()=>e.toValue(i),c=>c&&m()),{objects:r,poll:m,isFirstPoll:u}}function P(t,a){const n=e.ref(void 0);return e.watch(()=>e.toValue(t),async(i,l,o)=>{let r=!0;o(()=>{r=!1}),n.value=void 0;try{const s=await a(i);r&&(n.value=s)}catch(s){if(!r)return;s instanceof G?n.value=null:console.error(s)}},{immediate:!0}),{output:n}}function L(t){return t===void 0?"Loading...":t===null?"Not found":t}function U(t){const a=N(),{output:n}=P(t,a.actorToHandle.bind(a));return{handle:n}}const V=e.defineComponent({__name:"ActorToHandle",props:{actor:{}},setup(t){const a=t,n=e.toRef(a,"actor"),{handle:i}=U(n);return(l,o)=>e.renderSlot(l.$slots,"default",{handle:e.unref(i)},()=>[e.createElementVNode("span",null,e.toDisplayString(e.unref(L)(e.unref(i))),1)])}}),J=["data-url"],K={key:0},Q={key:1},X={key:0},Y={key:1},Z={key:0},ee=["disabled"],te={key:1},oe={key:2},B=e.defineComponent({__name:"ObjectInfo",props:{object:{}},setup(t){const a=N(),n=e.ref(!1);async function i(l,o){n.value=!0,await new Promise(r=>setTimeout(r,0)),confirm("Are you sure you want to delete this object? It cannot be undone.")&&await a.delete(l,o),n.value=!1}return(l,o)=>t.object?(e.openBlock(),e.createElementBlock("article",{key:0,"data-url":t.object.url},[e.createElementVNode("header",null,[o[4]||(o[4]=e.createElementVNode("h2",null,"Graffiti Object",-1)),e.createElementVNode("dl",null,[o[1]||(o[1]=e.createElementVNode("dt",null,"Object URL",-1)),e.createElementVNode("dd",null,[e.createElementVNode("code",null,e.toDisplayString(t.object.url),1)]),o[2]||(o[2]=e.createElementVNode("dt",null,"Actor",-1)),e.createElementVNode("dd",null,[e.createElementVNode("code",null,e.toDisplayString(t.object.actor),1)]),o[3]||(o[3]=e.createElementVNode("dt",null,"Handle",-1)),e.createElementVNode("dd",null,[e.createVNode(V,{actor:t.object.actor},null,8,["actor"])])])]),e.createElementVNode("section",null,[o[5]||(o[5]=e.createElementVNode("h3",null,"Content",-1)),e.createElementVNode("pre",null,e.toDisplayString(t.object.value),1)]),e.createElementVNode("section",null,[o[10]||(o[10]=e.createElementVNode("h3",null,"Allowed Actors",-1)),Array.isArray(t.object.allowed)?t.object.allowed.length===0?(e.openBlock(),e.createElementBlock("p",Q,[...o[7]||(o[7]=[e.createElementVNode("em",null,"Noone",-1)])])):e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("p",K,[...o[6]||(o[6]=[e.createElementVNode("em",null,"Public",-1)])])),e.createElementVNode("ul",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.object.allowed,r=>(e.openBlock(),e.createElementBlock("li",{key:r},[e.createElementVNode("dl",null,[o[8]||(o[8]=e.createElementVNode("dt",null,"Actor",-1)),e.createElementVNode("dd",null,[e.createElementVNode("code",null,e.toDisplayString(r),1)]),o[9]||(o[9]=e.createElementVNode("dt",null,"Handle",-1)),e.createElementVNode("dd",null,[e.createVNode(V,{actor:r},null,8,["actor"])])])]))),128))])]),e.createElementVNode("section",null,[o[12]||(o[12]=e.createElementVNode("h3",null,"Channels",-1)),t.object.channels?.length?(e.openBlock(),e.createElementBlock("ul",X,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.object.channels,r=>(e.openBlock(),e.createElementBlock("li",{key:r},[e.createElementVNode("code",null,e.toDisplayString(r),1)]))),128))])):(e.openBlock(),e.createElementBlock("p",Y,[...o[11]||(o[11]=[e.createElementVNode("em",null,"No channels",-1)])]))]),e.createElementVNode("footer",null,[e.createElementVNode("nav",null,[e.createElementVNode("ul",null,[l.$graffitiSession.value?.actor===t.object.actor?(e.openBlock(),e.createElementBlock("li",Z,[e.createElementVNode("button",{disabled:n.value,onClick:o[0]||(o[0]=r=>i(t.object,l.$graffitiSession.value))},e.toDisplayString(n.value?"Deleting...":"Delete"),9,ee)])):e.createCommentVNode("",!0)])])])],8,J)):t.object===null?(e.openBlock(),e.createElementBlock("article",te,[...o[13]||(o[13]=[e.createElementVNode("header",null,[e.createElementVNode("h2",null,"Graffiti Object")],-1),e.createElementVNode("p",null,[e.createElementVNode("em",null,"Object not found")],-1)])])):(e.openBlock(),e.createElementBlock("article",oe,[...o[14]||(o[14]=[e.createElementVNode("header",null,[e.createElementVNode("h2",null,"Graffiti Object")],-1),e.createElementVNode("p",null,[e.createElementVNode("em",null,"Loading...")],-1)])]))}}),ne={key:0},re={key:1},O=e.defineComponent({__name:"Discover",props:{channels:{},schema:{},session:{},autopoll:{type:Boolean}},setup(t){const a=t,{objects:n,poll:i,isFirstPoll:l}=T(e.toRef(a,"channels"),e.toRef(a,"schema"),e.toRef(a,"session"),e.toRef(a,"autopoll"));return(o,r)=>e.renderSlot(o.$slots,"default",{objects:e.unref(n),poll:e.unref(i),isFirstPoll:e.unref(l)},()=>[e.unref(l)?(e.openBlock(),e.createElementBlock("p",re,[...r[0]||(r[0]=[e.createElementVNode("em",null," Loading... ",-1)])])):(e.openBlock(),e.createElementBlock("ul",ne,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(n),s=>(e.openBlock(),e.createElementBlock("li",{key:s.url},[e.createVNode(B,{object:s},null,8,["object"])]))),128))]))])}});function H(t,a,n){const i=b(),l=e.ref(void 0);let o=async()=>{};const r=async()=>o();let s;return e.onScopeDispose(()=>{s?.return(null)}),e.watch(()=>[e.toValue(t),e.toValue(a),e.toValue(n)],(m,u,k)=>{l.value=void 0;const p=i.synchronizeGet(...m);s=p;let y=!0;k(()=>{y=!1,p.return(null)}),(async()=>{for await(const c of p){if(!y)return;c.tombstone?l.value=null:l.value=c.object}})();let f=!1;o=async()=>{if(!(f||!y)){f=!0;try{await i.get(...m)}catch(c){c instanceof G||console.error(c)}await new Promise(c=>setTimeout(c,0)),f=!1}},r()},{immediate:!0}),{object:l,poll:r}}const C=e.defineComponent({__name:"Get",props:{url:{},schema:{},session:{}},setup(t){const a=t,{object:n,poll:i}=H(e.toRef(a,"url"),e.toRef(a,"schema"),e.toRef(a,"session"));return(l,o)=>e.renderSlot(l.$slots,"default",{object:e.unref(n),poll:e.unref(i)},()=>[e.createVNode(B,{object:e.unref(n)},null,8,["object"])])}});function z(t,a,n){const i=b(),l=e.ref(void 0),o=e.ref(0);let r=null,s=()=>{};function m(){return r||(o.value++,r=new Promise(u=>{s=()=>{r=null,u()}}),r)}return e.watch(()=>({args:[e.toValue(t),e.toValue(a),e.toValue(n)],pollCounter:o.value}),async({args:u},k,p)=>{l.value?.dataUrl&&URL.revokeObjectURL(l.value.dataUrl),l.value=void 0;let y=!0;p(()=>{y=!1});try{const{data:f,actor:c,allowed:A}=await i.getMedia(...u);if(!y)return;const w=URL.createObjectURL(f);l.value={data:f,dataUrl:w,actor:c,allowed:A}}catch(f){if(!y)return;f instanceof G?l.value=null:console.error(f)}finally{s()}},{immediate:!0}),e.onScopeDispose(()=>{s(),l.value?.dataUrl&&URL.revokeObjectURL(l.value.dataUrl)}),{media:l,poll:m}}const le=["src","alt"],ae=["src","alt"],ie=["src","alt"],se=["src","alt"],ce=["data","alt"],ue={key:6},fe={key:7},M=e.defineComponent({__name:"GetMedia",props:{url:{},accept:{},session:{}},setup(t){const a=t,{media:n,poll:i}=z(e.toRef(a,"url"),e.toRef(a,"accept"),e.toRef(a,"session"));function l(){n.value&&(window.location.href=n.value.dataUrl)}return(o,r)=>e.renderSlot(o.$slots,"default",{media:e.unref(n),poll:e.unref(i)},()=>[e.unref(n)?.data.type.startsWith("image/")?(e.openBlock(),e.createElementBlock("img",{key:0,src:e.unref(n).dataUrl,alt:`An image by ${e.unref(n).actor}`},null,8,le)):e.unref(n)?.data.type.startsWith("video/")?(e.openBlock(),e.createElementBlock("video",{key:1,controls:"",src:e.unref(n).dataUrl,alt:`A video by ${e.unref(n).actor}`},null,8,ae)):e.unref(n)?.data.type.startsWith("audio/")?(e.openBlock(),e.createElementBlock("audio",{key:2,controls:"",src:e.unref(n).dataUrl,alt:`Audio by ${e.unref(n).actor}`},null,8,ie)):e.unref(n)?.data.type==="text/html"?(e.openBlock(),e.createElementBlock("iframe",{key:3,src:e.unref(n).dataUrl,alt:`HTML by ${e.unref(n).actor}`,sandbox:""},null,8,se)):e.unref(n)?.data.type.startsWith("application/pdf")?(e.openBlock(),e.createElementBlock("object",{key:4,data:e.unref(n).dataUrl,type:"application/pdf",alt:`PDF by ${e.unref(n).actor}`},null,8,ce)):e.unref(n)?(e.openBlock(),e.createElementBlock("button",{key:5,onClick:l},"Download")):e.unref(n)===null?(e.openBlock(),e.createElementBlock("p",ue,[...r[0]||(r[0]=[e.createElementVNode("em",null,"Media not found",-1)])])):(e.openBlock(),e.createElementBlock("p",fe,[...r[1]||(r[1]=[e.createElementVNode("em",null," Loading... ",-1)])]))])}});function F(t){const a=N(),{output:n}=P(t,a.handleToActor.bind(a));return{actor:n}}const I=e.defineComponent({__name:"HandleToActor",props:{handle:{}},setup(t){const a=t,n=e.toRef(a,"handle"),{actor:i}=F(n);return(l,o)=>e.renderSlot(l.$slots,"default",{actor:e.unref(i)},()=>[e.createElementVNode("span",null,e.toDisplayString(e.unref(L)(e.unref(i))),1)])}}),de={install(t,a){const n=a.graffiti,i=new _.GraffitiSynchronize(n),l=e.ref(void 0);i.sessionEvents.addEventListener("initialized",async o=>{const r=o.detail;if(r&&r.error&&console.error(r.error),r&&r.href){const s=t.config.globalProperties.$router;if(s){const m=s.options.history.base,u=new URL(r.href);u.pathname.startsWith(m)&&(u.pathname=u.pathname.slice(m.length)),await s.replace(u.pathname+u.search+u.hash)}}l.value||(l.value=null)}),i.sessionEvents.addEventListener("login",o=>{const r=o.detail;if(r.error){console.error("Error logging in:"),console.error(r.error);return}else l.value=r.session}),i.sessionEvents.addEventListener("logout",o=>{const r=o.detail;r.error?(console.error("Error logging out:"),console.error(r.error)):l.value=null}),x(i),W(l),t.component("GraffitiDiscover",O),t.component("GraffitiGet",C),t.component("GraffitiGetMedia",M),t.component("GraffitiActorToHandle",V),t.component("GraffitiHandleToActor",I),t.component("GraffitiObjectInfo",B),t.config.globalProperties.$graffiti=i,t.config.globalProperties.$graffitiSession=l}},me=O,pe=C,ye=M,ve=V,Ee=I,ke=B;exports.GraffitiActorToHandle=ve;exports.GraffitiDiscover=me;exports.GraffitiGet=pe;exports.GraffitiGetMedia=ye;exports.GraffitiHandleToActor=Ee;exports.GraffitiObjectInfo=ke;exports.GraffitiPlugin=de;exports.useGraffiti=N;exports.useGraffitiActorToHandle=U;exports.useGraffitiDiscover=T;exports.useGraffitiGet=H;exports.useGraffitiGetMedia=z;exports.useGraffitiHandleToActor=F;exports.useGraffitiSession=q;exports.useGraffitiSynchronize=b;
2
2
  //# sourceMappingURL=plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../node_modules/@graffiti-garden/api/dist/index.mjs","../../src/globals.ts","../../src/composables/discover.ts","../../src/composables/resolve-string.ts","../../src/composables/actor-to-handle.ts","../../src/components/ActorToHandle.vue","../../src/components/ObjectInfo.vue","../../src/components/Discover.vue","../../src/composables/get.ts","../../src/components/Get.vue","../../src/composables/get-media.ts","../../src/components/GetMedia.vue","../../src/composables/handle-to-actor.ts","../../src/components/HandleToActor.vue","../../src/plugin.ts"],"sourcesContent":["var a=class{};var S={type:\"object\",properties:{value:{type:\"object\"},channels:{type:\"array\",items:{type:\"string\"}},allowed:{type:\"array\",items:{type:\"string\"},nullable:!0},url:{type:\"string\"},actor:{type:\"string\"}},additionalProperties:!1,required:[\"value\",\"channels\",\"actor\",\"url\"]},l={...S,required:[\"value\",\"channels\"]};var s=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorForbidden\",Object.setPrototypeOf(this,t.prototype)}},o=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorNotFound\",Object.setPrototypeOf(this,t.prototype)}},i=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorInvalidSchema\",Object.setPrototypeOf(this,t.prototype)}},n=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorSchemaMismatch\",Object.setPrototypeOf(this,t.prototype)}},c=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorTooLarge\",Object.setPrototypeOf(this,t.prototype)}},f=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorNotAcceptable\",Object.setPrototypeOf(this,t.prototype)}};function u(t){return typeof t==\"string\"?t:t.url}function G(t,e){try{return t.compile(e)}catch(r){throw new i(r instanceof Error?r.message:void 0)}}function b(t,e){return!Array.isArray(t.allowed)||typeof e?.actor==\"string\"&&(t.actor===e.actor||t.allowed.includes(e.actor))}function j(t,e,r){t.actor!==r?.actor&&(t.allowed=t.allowed&&r?[r.actor]:void 0,t.channels=t.channels.filter(m=>e.includes(m)))}export{a as Graffiti,s as GraffitiErrorForbidden,i as GraffitiErrorInvalidSchema,f as GraffitiErrorNotAcceptable,o as GraffitiErrorNotFound,n as GraffitiErrorSchemaMismatch,c as GraffitiErrorTooLarge,S as GraffitiObjectJSONSchema,l as GraffitiPostObjectJSONSchema,G as compileGraffitiObjectSchema,b as isActorAllowedGraffitiObject,j as maskGraffitiObject,u as unpackObjectUrl};\n//# sourceMappingURL=index.mjs.map\n","import type { Ref } from \"vue\";\nimport type { Graffiti, GraffitiSession } from \"@graffiti-garden/api\";\nimport type { GraffitiSynchronize } from \"@graffiti-garden/wrapper-synchronize\";\n\nconst globals: {\n graffitiSynchronize?: GraffitiSynchronize;\n graffitiSession?: Ref<GraffitiSession | undefined | null>;\n} = {};\n\nexport function setGraffitiSession(\n session: Ref<GraffitiSession | undefined | null>,\n) {\n if (!globals.graffitiSession) {\n globals.graffitiSession = session;\n } else {\n throw new Error(\n \"Graffiti session already set - plugin installed multiple times?\",\n );\n }\n}\n\nexport function setGraffitiSynchronize(synchronize: GraffitiSynchronize) {\n if (!globals.graffitiSynchronize) {\n globals.graffitiSynchronize = synchronize;\n } else {\n throw new Error(\n \"Graffiti synchronize already set - plugin installed multiple times?\",\n );\n }\n}\n\n/**\n * Returns the global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance\n * that has been wrapped by the {@link GraffitiPlugin} with the [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html).\n * @throws If the {@link GraffitiPlugin} is not installed\n */\nexport function useGraffitiSynchronize() {\n const graffiti = globals.graffitiSynchronize;\n if (!graffiti) {\n throw new Error(\n \"No Graffiti instance provided, did you forget to install the plugin?\",\n );\n }\n return graffiti;\n}\n\n/**\n * Returns the global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance.\n *\n * In Vue templates and the [options API](https://vuejs.org/guide/introduction.html#options-api)\n * use may use the global variable {@link ComponentCustomProperties.$graffiti | $graffiti} instead.\n *\n * This is the same Graffiti registered with the {@link GraffitiPlugin}\n * via {@link GraffitiPluginOptions.graffiti}, only it has been wrapped\n * with [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html).\n * Be sure to use the wrapped instance to enable reactivity.\n *\n * @throws If the {@link GraffitiPlugin} is not installed\n */\nexport function useGraffiti(): Graffiti {\n return useGraffitiSynchronize();\n}\n\n/**\n * Returns a global reactive [GraffitiSession](https://api.graffiti.garden/interfaces/GraffitiSession.html) instance\n * as a [Vue ref](https://vuejs.org/api/reactivity-core.html#ref).\n *\n * In Vue templates and the [options API](https://vuejs.org/guide/introduction.html#options-api)\n * use the global variable {@link ComponentCustomProperties.$graffitiSession | $graffitiSession} instead.\n *\n * While the application is loading and restoring any previous sessions,\n * the value will be `undefined`. If the user is not logged in,\n * the value will be `null`.\n *\n * This only keeps track of one session. If your app needs\n * to support multiple login sessions, you'll need to manage them\n * yourself using [`Graffiti.sessionEvents`](https://api.graffiti.garden/classes/Graffiti.html#sessionevents).\n * @throws If the {@link GraffitiPlugin} is not installed\n */\nexport function useGraffitiSession() {\n const session = globals.graffitiSession;\n if (!session) {\n throw new Error(\n \"No Graffiti session provided, did you forget to install the plugin?\",\n );\n }\n return session;\n}\n","import type {\n GraffitiObject,\n GraffitiObjectStreamContinue,\n GraffitiObjectStreamContinueEntry,\n GraffitiObjectStreamError,\n GraffitiObjectStreamReturn,\n GraffitiSession,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter, Ref } from \"vue\";\nimport { ref, toValue, watch, onScopeDispose } from \"vue\";\nimport { useGraffitiSynchronize } from \"../globals\";\n\n/**\n * The [Graffiti.discover](https://api.graffiti.garden/classes/Graffiti.html#discover)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiDiscover}.\n *\n * The arguments of this composable are largely the same as Graffiti.discover,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * There is one additional optional argument `autopoll`, which when `true`,\n * will automatically poll for new objects.\n * As they change the arguments change, the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `objects`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * an array of Graffiti objects.\n * - `poll`: A function that can be called to manually check for objects.\n * - `isFirstPoll`: A boolean [ref](https://vuejs.org/api/reactivity-core.html#ref)\n * that indicates if the *first* poll after a change of arguments is currently running.\n * It may be used to show a loading spinner or disable a button, or it can be watched\n * to know when the `objects` array is ready to use.\n */\nexport function useGraffitiDiscover<Schema extends JSONSchema>(\n channels: MaybeRefOrGetter<string[]>,\n schema: MaybeRefOrGetter<Schema>,\n session?: MaybeRefOrGetter<GraffitiSession | undefined | null>,\n /**\n * Whether to automatically poll for new objects.\n */\n autopoll: MaybeRefOrGetter<boolean> = false,\n) {\n const graffiti = useGraffitiSynchronize();\n\n // Output\n const objectsRaw: Map<string, GraffitiObject<Schema>> = new Map();\n const objects: Ref<GraffitiObject<Schema>[]> = ref([]);\n let poll_ = async () => {};\n const poll = async () => poll_();\n const isFirstPoll = ref(true);\n\n // Maintain iterators for disposal\n let syncIterator: AsyncGenerator<GraffitiObjectStreamContinueEntry<Schema>>;\n let discoverIterator: GraffitiObjectStreamContinue<Schema>;\n onScopeDispose(() => {\n syncIterator?.return(null);\n discoverIterator?.return({\n continue: () => discoverIterator,\n cursor: \"\",\n });\n });\n\n const refresh = ref(0);\n function restartWatch(timeout = 0) {\n setTimeout(() => {\n refresh.value++;\n }, timeout);\n }\n watch(\n () => ({\n args: [toValue(channels), toValue(schema), toValue(session)] as const,\n refresh: refresh.value,\n }),\n ({ args }, _prev, onInvalidate) => {\n // Reset the output\n objectsRaw.clear();\n objects.value = [];\n isFirstPoll.value = true;\n\n // Initialize new iterators\n const mySyncIterator = graffiti.synchronizeDiscover<Schema>(...args);\n syncIterator = mySyncIterator;\n let myDiscoverIterator: GraffitiObjectStreamContinue<Schema>;\n\n // Set up automatic iterator cleanup\n let active = true;\n onInvalidate(() => {\n active = false;\n mySyncIterator.return(null);\n myDiscoverIterator?.return({\n continue: () => discoverIterator,\n cursor: \"\",\n });\n });\n\n // Start to synchronize in the background\n // (all polling results will go through here)\n let batchFlattenPromise: Promise<void> | undefined = undefined;\n (async () => {\n for await (const result of mySyncIterator) {\n if (!active) break;\n if (result.tombstone) {\n objectsRaw.delete(result.object.url);\n } else {\n objectsRaw.set(result.object.url, result.object);\n }\n // Flatten objects in batches to prevent\n // excessive re-rendering\n if (!batchFlattenPromise) {\n batchFlattenPromise = new Promise<void>((resolve) => {\n setTimeout(() => {\n if (active) {\n objects.value = Array.from(objectsRaw.values());\n }\n batchFlattenPromise = undefined;\n resolve();\n }, 50);\n });\n }\n }\n })();\n\n // Then set up a polling function\n let polling = false;\n let continueFn: GraffitiObjectStreamReturn<Schema>[\"continue\"] = () =>\n graffiti.discover<Schema>(...args);\n poll_ = async () => {\n if (polling || !active) return;\n polling = true;\n\n // Try to start the iterator\n try {\n myDiscoverIterator = continueFn(args[2]);\n } catch (e) {\n // Discovery is lazy so this should not happen,\n // wait a bit before retrying\n return restartWatch(5000);\n }\n if (!active) return;\n discoverIterator = myDiscoverIterator;\n\n while (true) {\n let result: IteratorResult<\n | GraffitiObjectStreamContinueEntry<Schema>\n | GraffitiObjectStreamError,\n GraffitiObjectStreamReturn<Schema>\n >;\n try {\n result = await myDiscoverIterator.next();\n } catch (e) {\n if (e instanceof GraffitiErrorNotFound) {\n // The cursor has expired, we need to start from scratch.\n return restartWatch();\n } else {\n // If something else went wrong, wait a bit before retrying\n return restartWatch(5000);\n }\n }\n if (!active) return;\n if (result.done) {\n continueFn = result.value.continue;\n break;\n } else if (result.value.error) {\n // Non-fatal errors do not stop the stream\n console.error(result.value.error);\n }\n }\n\n // Wait for sync to receive updates\n await new Promise((resolve) => setTimeout(resolve, 0));\n // And wait for pending results to be flattened\n if (batchFlattenPromise) await batchFlattenPromise;\n\n if (!active) return;\n polling = false;\n isFirstPoll.value = false;\n if (toValue(autopoll)) poll();\n };\n poll();\n },\n { immediate: true },\n );\n\n // Start polling if autopoll turns true\n watch(\n () => toValue(autopoll),\n (value) => value && poll(),\n );\n\n return {\n objects,\n poll,\n isFirstPoll,\n };\n}\n","import { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter } from \"vue\";\nimport { ref, toValue, watch } from \"vue\";\n\nexport function useResolveString(\n input: MaybeRefOrGetter<string>,\n resolve: (input: string) => Promise<string>,\n) {\n const output = ref<string | null | undefined>(undefined);\n\n watch(\n () => toValue(input),\n async (input, _prev, onInvalidate) => {\n let active = true;\n onInvalidate(() => {\n active = false;\n });\n\n output.value = undefined;\n\n try {\n const resolved = await resolve(input);\n if (active) output.value = resolved;\n } catch (err) {\n if (!active) return;\n\n if (err instanceof GraffitiErrorNotFound) {\n output.value = null;\n } else {\n console.error(err);\n }\n }\n },\n { immediate: true },\n );\n\n return {\n output,\n };\n}\n\nexport function displayOutput(output: string | null | undefined) {\n if (output === undefined) return \"Loading...\";\n if (output === null) return \"Not found\";\n return output;\n}\n","import type { MaybeRefOrGetter } from \"vue\";\nimport { useGraffiti } from \"../globals\";\nimport { useResolveString } from \"./resolve-string\";\n\n/**\n * The [Graffiti.actorToHandle](https://api.graffiti.garden/classes/Graffiti.html#actortohandle)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiActorToHandle}.\n *\n * The arguments of this composable are the same as Graffiti.actorToHandle,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `handle`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved handle, if it exists. If the handle cannot be found, the result\n * is `null`. If the handle is still being fetched, the result is `undefined`.\n */\nexport function useGraffitiActorToHandle(actor: MaybeRefOrGetter<string>) {\n const graffiti = useGraffiti();\n const { output } = useResolveString(\n actor,\n graffiti.actorToHandle.bind(graffiti),\n );\n return { handle: output };\n}\n","<script setup lang=\"ts\">\nimport { toRef } from \"vue\";\nimport { displayOutput } from \"../composables/resolve-string\";\nimport { useGraffitiActorToHandle } from \"../composables/actor-to-handle\";\n\nconst props = defineProps<{ actor: string }>();\nconst actor = toRef(props, \"actor\");\n\nconst { handle } = useGraffitiActorToHandle(actor);\n</script>\n\n<template>\n <slot :handle=\"handle\">\n <span> {{ displayOutput(handle) }} </span>\n </slot>\n</template>\n","<script setup lang=\"ts\">\nimport type { GraffitiObjectBase, GraffitiSession } from \"@graffiti-garden/api\";\nimport ActorToHandle from \"./ActorToHandle.vue\";\nimport { useGraffiti } from \"../globals\";\nimport { ref } from \"vue\";\n\ndefineProps<{\n object: GraffitiObjectBase | null | undefined;\n}>();\n\nconst graffiti = useGraffiti();\nconst deleting = ref(false);\nasync function deleteObject(\n object: GraffitiObjectBase,\n session: GraffitiSession,\n) {\n deleting.value = true;\n await new Promise((resolve) => setTimeout(resolve, 0));\n if (\n confirm(\n \"Are you sure you want to delete this object? It cannot be undone.\",\n )\n ) {\n await graffiti.delete(object, session);\n }\n deleting.value = false;\n}\n</script>\n\n<template>\n <article v-if=\"object\" :data-url=\"object.url\">\n <header>\n <h2>Graffiti Object</h2>\n\n <dl>\n <dt>Object URL</dt>\n <dd>\n <code>{{ object.url }}</code>\n </dd>\n\n <dt>Actor</dt>\n <dd>\n <code>{{ object.actor }}</code>\n </dd>\n\n <dt>Handle</dt>\n <dd>\n <ActorToHandle :actor=\"object.actor\" />\n </dd>\n </dl>\n </header>\n\n <section>\n <h3>Content</h3>\n <pre>{{ object.value }}</pre>\n </section>\n\n <section>\n <h3>Allowed Actors</h3>\n\n <p v-if=\"!Array.isArray(object.allowed)\">\n <em>Public</em>\n </p>\n <p v-else-if=\"object.allowed.length === 0\">\n <em>Noone</em>\n </p>\n <ul>\n <li v-for=\"actor in object.allowed\" :key=\"actor\">\n <dl>\n <dt>Actor</dt>\n <dd>\n <code>{{ actor }}</code>\n </dd>\n <dt>Handle</dt>\n <dd>\n <ActorToHandle :actor=\"actor\" />\n </dd>\n </dl>\n </li>\n </ul>\n </section>\n\n <section>\n <h3>Channels</h3>\n\n <ul v-if=\"object.channels?.length\">\n <li v-for=\"channel in object.channels\" :key=\"channel\">\n <code>{{ channel }}</code>\n </li>\n </ul>\n <p v-else>\n <em>No channels</em>\n </p>\n </section>\n\n <footer>\n <nav>\n <ul>\n <li v-if=\"$graffitiSession.value?.actor === object.actor\">\n <button\n :disabled=\"deleting\"\n @click=\"\n deleteObject(object, $graffitiSession.value)\n \"\n >\n {{ deleting ? \"Deleting...\" : \"Delete\" }}\n </button>\n </li>\n </ul>\n </nav>\n </footer>\n </article>\n\n <article v-else-if=\"object === null\">\n <header>\n <h2>Graffiti Object</h2>\n </header>\n <p><em>Object not found</em></p>\n </article>\n\n <article v-else>\n <header>\n <h2>Graffiti Object</h2>\n </header>\n <p><em>Loading...</em></p>\n </article>\n</template>\n","<script setup lang=\"ts\" generic=\"Schema extends JSONSchema\">\nimport { toRef } from \"vue\";\nimport type {\n GraffitiSession,\n JSONSchema,\n GraffitiObject,\n} from \"@graffiti-garden/api\";\nimport { useGraffitiDiscover } from \"../composables/discover\";\nimport ObjectInfo from \"./ObjectInfo.vue\";\n\nconst props = defineProps<{\n channels: string[];\n schema: Schema;\n session?: GraffitiSession | null;\n autopoll?: boolean;\n}>();\n\ndefineSlots<{\n default?(props: {\n objects: GraffitiObject<Schema>[];\n poll: () => Promise<void>;\n isFirstPoll: boolean;\n }): any;\n}>();\n\nconst { objects, poll, isFirstPoll } = useGraffitiDiscover<Schema>(\n toRef(props, \"channels\"),\n toRef(props, \"schema\"),\n toRef(props, \"session\"),\n toRef(props, \"autopoll\"),\n);\n</script>\n\n<template>\n <slot :objects=\"objects\" :poll=\"poll\" :isFirstPoll=\"isFirstPoll\">\n <ul v-if=\"!isFirstPoll\">\n <li v-for=\"object in objects\" :key=\"object.url\">\n <ObjectInfo :object=\"object\" />\n </li>\n </ul>\n <p v-else>\n <em> Loading... </em>\n </p>\n </slot>\n</template>\n","import type {\n GraffitiObject,\n GraffitiObjectUrl,\n GraffitiObjectStreamContinueEntry,\n GraffitiSession,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter, Ref } from \"vue\";\nimport { ref, toValue, watch, onScopeDispose } from \"vue\";\nimport { useGraffitiSynchronize } from \"../globals\";\n\n/**\n * The [Graffiti.get](https://api.graffiti.garden/classes/Graffiti.html#get)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiGet}.\n *\n * The arguments of this composable are the same as Graffiti.get,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `object`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved Graffiti object, if it exists. If the object cannot be found,\n * the result is `null`. If the object is still being fetched, the result is `undefined`.\n * - `poll`: A function that can be called to manually check if the object has changed.\n */\nexport function useGraffitiGet<Schema extends JSONSchema>(\n url: MaybeRefOrGetter<GraffitiObjectUrl | string>,\n schema: MaybeRefOrGetter<Schema>,\n session?: MaybeRefOrGetter<GraffitiSession | undefined | null>,\n): {\n object: Ref<GraffitiObject<Schema> | null | undefined>;\n poll: () => Promise<void>;\n} {\n const graffiti = useGraffitiSynchronize();\n\n const object: Ref<GraffitiObject<Schema> | null | undefined> = ref(undefined);\n let poll_ = async () => {};\n const poll = async () => poll_();\n\n let iterator: AsyncGenerator<GraffitiObjectStreamContinueEntry<Schema>>;\n onScopeDispose(() => {\n iterator?.return(null);\n });\n\n watch(\n () => [toValue(url), toValue(schema), toValue(session)] as const,\n (args, _prev, onInvalidate) => {\n // Reset the object value (undefined = \"loading\")\n object.value = undefined;\n\n // Initialize a new iterator\n const myIterator = graffiti.synchronizeGet<Schema>(...args);\n iterator = myIterator;\n\n // Make sure to dispose of the iterator when invalidated\n let active = true;\n onInvalidate(() => {\n active = false;\n myIterator.return(null);\n });\n\n // Listen to the iterator in the background,\n // it will receive results from polling below\n (async () => {\n for await (const result of myIterator) {\n if (!active) return;\n if (result.tombstone) {\n object.value = null;\n } else {\n object.value = result.object;\n }\n }\n })();\n\n // Then set up a polling function\n let polling = false;\n poll_ = async () => {\n if (polling || !active) return;\n polling = true;\n try {\n await graffiti.get<Schema>(...args);\n } catch (e) {\n if (!(e instanceof GraffitiErrorNotFound)) {\n console.error(e);\n }\n }\n\n // Wait for sync to receive the update\n await new Promise((resolve) => setTimeout(resolve, 0));\n polling = false;\n };\n poll();\n },\n { immediate: true },\n );\n\n return {\n object,\n poll,\n };\n}\n","<script setup lang=\"ts\" generic=\"Schema extends JSONSchema\">\nimport { toRef } from \"vue\";\nimport type {\n GraffitiObjectUrl,\n GraffitiObject,\n GraffitiSession,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport { useGraffitiGet } from \"../composables/get\";\nimport ObjectInfo from \"./ObjectInfo.vue\";\n\nconst props = defineProps<{\n url: string | GraffitiObjectUrl;\n schema: Schema;\n session?: GraffitiSession | null;\n}>();\n\ndefineSlots<{\n default?(props: {\n object: GraffitiObject<Schema> | undefined | null;\n poll: () => Promise<void>;\n }): any;\n}>();\n\nconst { object, poll } = useGraffitiGet<Schema>(\n toRef(props, \"url\"),\n toRef(props, \"schema\"),\n toRef(props, \"session\"),\n);\n</script>\n\n<template>\n <slot :object=\"object\" :poll=\"poll\">\n <ObjectInfo :object=\"object\" />\n </slot>\n</template>\n","import type {\n GraffitiMedia,\n GraffitiMediaRequirements,\n GraffitiSession,\n} from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter, Ref } from \"vue\";\nimport { ref, toValue, watch, onScopeDispose } from \"vue\";\nimport { useGraffitiSynchronize } from \"../globals\";\n\n/**\n * The [Graffiti.getMedia](https://api.graffiti.garden/classes/Graffiti.html#getMedia)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiGetMedia}.\n *\n * The arguments of this composable are the same as Graffiti.getMedia,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `media`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved Graffiti media, if it exists. The media will include a `dataUrl` property\n * that can be used to directly display the media in a template. If the media has been deleted,\n * the result is `null`. If the media is still being fetched, the result is `undefined`.\n * - `poll`: A function that can be called to manually check if the media has changed.\n */\nexport function useGraffitiGetMedia(\n url: MaybeRefOrGetter<string>,\n requirements: MaybeRefOrGetter<GraffitiMediaRequirements>,\n session?: MaybeRefOrGetter<GraffitiSession | undefined | null>,\n): {\n media: Ref<(GraffitiMedia & { dataUrl: string }) | null | undefined>;\n poll: () => Promise<void>;\n} {\n const graffiti = useGraffitiSynchronize();\n const media = ref<(GraffitiMedia & { dataUrl: string }) | null | undefined>(\n undefined,\n );\n\n // The \"poll counter\" is a hack to get\n // watch to refresh\n const pollCounter = ref(0);\n let pollPromise: Promise<void> | null = null;\n let resolvePoll = () => {};\n function poll() {\n if (pollPromise) return pollPromise;\n pollCounter.value++;\n // Wait until the watch finishes and calls\n // \"pollResolve\" to finish the poll\n pollPromise = new Promise<void>((resolve) => {\n resolvePoll = () => {\n pollPromise = null;\n resolve();\n };\n });\n return pollPromise;\n }\n watch(\n () => ({\n args: [toValue(url), toValue(requirements), toValue(session)] as const,\n pollCounter: pollCounter.value,\n }),\n async ({ args }, _prev, onInvalidate) => {\n // Revoke the data URL to prevent a memory leak\n if (media.value?.dataUrl) {\n URL.revokeObjectURL(media.value.dataUrl);\n }\n media.value = undefined;\n\n let active = true;\n onInvalidate(() => {\n active = false;\n });\n\n try {\n const { data, actor, allowed } = await graffiti.getMedia(...args);\n if (!active) return;\n const dataUrl = URL.createObjectURL(data);\n media.value = {\n data,\n dataUrl,\n actor,\n allowed,\n };\n } catch (e) {\n if (!active) return;\n if (e instanceof GraffitiErrorNotFound) {\n media.value = null;\n } else {\n console.error(e);\n }\n } finally {\n resolvePoll();\n }\n },\n { immediate: true },\n );\n\n onScopeDispose(() => {\n resolvePoll();\n if (media.value?.dataUrl) {\n URL.revokeObjectURL(media.value.dataUrl);\n }\n });\n\n return {\n media,\n poll,\n };\n}\n","<script setup lang=\"ts\">\nimport { toRef } from \"vue\";\nimport type {\n GraffitiSession,\n GraffitiMediaRequirements,\n GraffitiMedia,\n} from \"@graffiti-garden/api\";\nimport { useGraffitiGetMedia } from \"../composables/get-media\";\n\nconst props = defineProps<{\n url: string;\n requirements: GraffitiMediaRequirements;\n session?: GraffitiSession | null;\n}>();\n\ndefineSlots<{\n default?(props: {\n media: (GraffitiMedia & { dataUrl: string }) | null | undefined;\n poll: () => Promise<void>;\n }): any;\n}>();\n\nconst { media, poll } = useGraffitiGetMedia(\n toRef(props, \"url\"),\n toRef(props, \"requirements\"),\n toRef(props, \"session\"),\n);\n\nfunction downloadMedia() {\n if (media.value) {\n window.location.href = media.value.dataUrl;\n }\n}\n</script>\n\n<template>\n <slot :media=\"media\" :poll=\"poll\">\n <img\n v-if=\"media?.data.type.startsWith('image/')\"\n :src=\"media.dataUrl\"\n :alt=\"`An image by ${media.actor}`\"\n />\n <video\n v-else-if=\"media?.data.type.startsWith('video/')\"\n controls\n :src=\"media.dataUrl\"\n :alt=\"`A video by ${media.actor}`\"\n />\n <audio\n v-else-if=\"media?.data.type.startsWith('audio/')\"\n controls\n :src=\"media.dataUrl\"\n :alt=\"`Audio by ${media.actor}`\"\n />\n <iframe\n v-else-if=\"media?.data.type === 'text/html'\"\n :src=\"media.dataUrl\"\n :alt=\"`HTML by ${media.actor}`\"\n sandbox=\"\"\n />\n <object\n v-else-if=\"media?.data.type.startsWith('application/pdf')\"\n :data=\"media.dataUrl\"\n type=\"application/pdf\"\n :alt=\"`PDF by ${media.actor}`\"\n />\n <button v-else-if=\"media\" @click=\"downloadMedia\">Download</button>\n <p v-else-if=\"media === null\">\n <em>Media not found</em>\n </p>\n <p v-else>\n <em> Loading... </em>\n </p>\n </slot>\n</template>\n","import type { MaybeRefOrGetter } from \"vue\";\nimport { useGraffiti } from \"../globals\";\nimport { useResolveString } from \"./resolve-string\";\n\n/**\n * The [Graffiti.handleToActor](https://api.graffiti.garden/classes/Graffiti.html#handletoactor)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiHandleToActor}.\n *\n * The arguments of this composable are the same as Graffiti.handleToActor,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `actor`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved actor, if it exists. If the actor cannot be found, the result\n * is `null`. If the actor is still being fetched, the result is `undefined`.\n */\nexport function useGraffitiHandleToActor(handle: MaybeRefOrGetter<string>) {\n const graffiti = useGraffiti();\n const { output } = useResolveString(\n handle,\n graffiti.handleToActor.bind(graffiti),\n );\n return { actor: output };\n}\n","<script setup lang=\"ts\">\nimport { toRef } from \"vue\";\nimport { displayOutput } from \"../composables/resolve-string\";\nimport { useGraffitiHandleToActor } from \"../composables/handle-to-actor\";\n\nconst props = defineProps<{ handle: string }>();\nconst handle = toRef(props, \"handle\");\n\nconst { actor } = useGraffitiHandleToActor(handle);\n</script>\n\n<template>\n <slot :actor=\"actor\">\n <span> {{ displayOutput(actor) }} </span>\n </slot>\n</template>\n","import type { App, Plugin, Ref } from \"vue\";\nimport { ref } from \"vue\";\nimport Discover from \"./components/Discover.vue\";\nimport Get from \"./components/Get.vue\";\nimport GetMedia from \"./components/GetMedia.vue\";\nimport ActorToHandle from \"./components/ActorToHandle.vue\";\nimport HandleToActor from \"./components/HandleToActor.vue\";\nimport ObjectInfo from \"./components/ObjectInfo.vue\";\nimport type {\n Graffiti,\n GraffitiSession,\n GraffitiLoginEvent,\n GraffitiLogoutEvent,\n GraffitiSessionInitializedEvent,\n} from \"@graffiti-garden/api\";\nimport { setGraffitiSession, setGraffitiSynchronize } from \"./globals\";\nimport type { Router } from \"vue-router\";\nimport { GraffitiSynchronize } from \"@graffiti-garden/wrapper-synchronize\";\n\ndeclare module \"vue\" {\n export interface ComponentCustomProperties {\n /**\n * Global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance.\n *\n * In the [composition API](https://vuejs.org/guide/introduction.html#composition-api)\n * use {@link useGraffiti} instead.\n *\n * This is the same Graffiti registered with the {@link GraffitiPlugin}\n * via {@link GraffitiPluginOptions.graffiti}, only it has been wrapped\n * with [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html).\n * Be sure to use the wrapped instance to enable reactivity.\n */\n $graffiti: Graffiti;\n /**\n * Global reactive [GraffitiSession](https://api.graffiti.garden/classes/GraffitiSession.html) instance\n * as a [Vue ref](https://vuejs.org/api/reactivity-core.html#ref).\n *\n * In the [composition API](https://vuejs.org/guide/introduction.html#composition-api)\n * use {@link useGraffitiSession} instead.\n *\n * While the application is loading and restoring any previous sessions,\n * the value will be `undefined`. If the user is not logged in,\n * the value will be `null`.\n *\n * This only keeps track of one session. If your app needs\n * to support multiple login sessions, you'll need to manage them\n * yourself using [`Graffiti.sessionEvents`](https://api.graffiti.garden/classes/Graffiti.html#sessionevents).\n */\n $graffitiSession: Ref<GraffitiSession | undefined | null>;\n }\n\n export interface GlobalComponents {\n GraffitiDiscover: typeof Discover;\n GraffitiGet: typeof Get;\n GraffitiGetMedia: typeof GetMedia;\n GraffitiActorToHandle: typeof ActorToHandle;\n GraffitiHandleToActor: typeof HandleToActor;\n GraffitiObjectInfo: typeof ObjectInfo;\n }\n}\nexport type { ComponentCustomProperties } from \"vue\";\n\n/**\n * Options for the {@link GraffitiPlugin}.\n */\nexport interface GraffitiPluginOptions {\n /**\n * An instance of the [Graffiti API](https://api.graffiti.garden/classes/Graffiti.html)\n * for the Vue.js plugin to use.\n * This instance, wrapped with [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html),\n * will be exposed in Vue templates as {@link ComponentCustomProperties.$graffiti | $graffiti}\n * and in setup functions as {@link useGraffiti}.\n * You must interact with Graffiti through these wrapped instances\n * to enable reactivity.\n */\n graffiti: Graffiti;\n}\n\n/**\n * A [Vue.js](https://vuejs.org/) plugin that wraps around\n * the [Graffiti API](https://api.graffiti.garden/classes/Graffiti.html)\n * to provide [reactive](https://en.wikipedia.org/wiki/Reactive_programming) versions\n * of various Graffiti API methods.\n *\n * These reactive methods are available as both\n * [renderless components](https://vuejs.org/guide/components/slots#renderless-components),\n * which make it possible to create a whole Graffiti app in an HTML template,\n * and [composables](https://vuejs.org/guide/reusability/composables.html),\n * which can be used in the programmatic [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * | [API](https://api.graffiti.garden/classes/Graffiti.html) method | [Composable](https://vuejs.org/guide/reusability/composables.html) | [Component](https://vuejs.org/guide/components/slots#renderless-components) |\n * | --- | --- | --- |\n * | [discover](https://api.graffiti.garden/classes/Graffiti.html#discover) | {@link useGraffitiDiscover} | {@link GraffitiDiscover} |\n * | [get](https://api.graffiti.garden/classes/Graffiti.html#get) | {@link useGraffitiGet} | {@link GraffitiGet} |\n * | [getMedia](https://api.graffiti.garden/classes/Graffiti.html#getmedia) | {@link useGraffitiGetMedia} | {@link GraffitiGetMedia} |\n * | [actorToHandle](https://api.graffiti.garden/classes/Graffiti.html#actortohandle) | {@link useGraffitiActorToHandle} | {@link GraffitiActorToHandle} |\n * | [handleToActor](https://api.graffiti.garden/classes/Graffiti.html#handletoactor) | {@link useGraffitiHandleToActor} | {@link GraffitiHandleToActor} |\n *\n * The plugin also exposes a global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance\n * and keeps track of the global [GraffitiSession](https://api.graffiti.garden/interfaces/GraffitiSession.html)\n * state as a reactive variable.\n * They are available in templates as global variables or in setup functions as\n * getter functions.\n *\n * | Global variabale | Getter |\n * | --- | --- |\n * | {@link ComponentCustomProperties.$graffiti | $graffiti } | {@link useGraffiti} |\n * | {@link ComponentCustomProperties.$graffitiSession | $graffitiSession } | {@link useGraffitiSession} |\n *\n * Finally, the plugin exposes an additional component, {@link GraffitiObjectInfo}\n * that can be use to generically display a Graffiti object for debugging purposes.\n * {@link GraffitiDiscover} and {@link GraffitiGet} show this output as\n * [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * if no template is provided\n *\n * [See the README for installation instructions](/).\n *\n * You can [try out live examples](/examples/), but basic usage looks like this:\n *\n * ```ts\n * import { createApp } from \"vue\";\n * import { GraffitiPlugin } from \"@graffiti-garden/vue\";\n * import { GraffitiLocal } from \"@graffiti-garden/implementation-local\";\n * import App from \"./App.vue\";\n *\n * createApp(App)\n * .use(GraffitiPlugin, {\n * graffiti: new GraffitiLocal(),\n * })\n * ```\n *\n * ```vue\n * <!-- App.vue -->\n * <template>\n * <button\n * v-if=\"$graffitiSession.value\"\n * @click=\"$graffiti.post({\n * value: { content: 'Hello, world!' },\n * channels: [ 'my-channel' ]\n * }, $graffitiSession.value)\"\n * >\n * Say Hello\n * </button>\n * <button v-else @click=\"$graffiti.login()\">\n * Log In to Say Hello\n * </button>\n *\n * <GraffitiDiscover\n * v-slot=\"{ objects }\"\n * :channels=\"[ 'my-channel' ]\"\n * :schema=\"{\n * properties: {\n * value: {\n * required: ['content'],\n * properties: {\n * content: { type: 'string' }\n * }\n * }\n * }\n * }\"\n * >\n * <ul>\n * <li\n * v-for=\"object in objects\"\n * :key=\"object.url\"\n * >\n * {{ object.value.content }}\n * </li>\n * </ul>\n * </GraffitiDiscover>\n * </template>\n * ```\n */\nexport const GraffitiPlugin: Plugin<GraffitiPluginOptions> = {\n install(app: App, options: GraffitiPluginOptions) {\n const graffitiBase = options.graffiti;\n const graffiti = new GraffitiSynchronize(graffitiBase);\n\n const graffitiSession = ref<GraffitiSession | undefined | null>(undefined);\n graffiti.sessionEvents.addEventListener(\"initialized\", async (evt) => {\n const detail = (evt as GraffitiSessionInitializedEvent).detail;\n\n if (detail && detail.error) {\n console.error(detail.error);\n }\n\n if (detail && detail.href) {\n // If we're using Vue Router, redirect to the URL after login\n const router = app.config.globalProperties.$router as\n | Router\n | undefined;\n if (router) {\n const base = router.options.history.base;\n const url = new URL(detail.href);\n if (url.pathname.startsWith(base)) {\n url.pathname = url.pathname.slice(base.length);\n }\n await router.replace(url.pathname + url.search + url.hash);\n }\n }\n\n // Set the session to \"null\" if the user is not logged in\n if (!graffitiSession.value) {\n graffitiSession.value = null;\n }\n });\n graffiti.sessionEvents.addEventListener(\"login\", (evt) => {\n const detail = (evt as GraffitiLoginEvent).detail;\n if (detail.error) {\n console.error(\"Error logging in:\");\n console.error(detail.error);\n return;\n } else {\n graffitiSession.value = detail.session;\n }\n });\n graffiti.sessionEvents.addEventListener(\"logout\", (evt) => {\n const detail = (evt as GraffitiLogoutEvent).detail;\n if (detail.error) {\n console.error(\"Error logging out:\");\n console.error(detail.error);\n } else {\n graffitiSession.value = null;\n }\n });\n\n setGraffitiSynchronize(graffiti);\n setGraffitiSession(graffitiSession);\n\n app.component(\"GraffitiDiscover\", Discover);\n app.component(\"GraffitiGet\", Get);\n app.component(\"GraffitiGetMedia\", GetMedia);\n app.component(\"GraffitiActorToHandle\", ActorToHandle);\n app.component(\"GraffitiHandleToActor\", HandleToActor);\n app.component(\"GraffitiObjectInfo\", ObjectInfo);\n app.config.globalProperties.$graffiti = graffiti;\n app.config.globalProperties.$graffitiSession = graffitiSession;\n },\n};\n\nexport { useGraffitiActorToHandle } from \"./composables/actor-to-handle\";\nexport { useGraffitiHandleToActor } from \"./composables/handle-to-actor\";\nexport { useGraffitiDiscover } from \"./composables/discover\";\nexport { useGraffitiGet } from \"./composables/get\";\nexport { useGraffitiGetMedia } from \"./composables/get-media\";\nexport {\n useGraffiti,\n useGraffitiSynchronize,\n useGraffitiSession,\n} from \"./globals\";\n\n/**\n * The [Graffiti.discover](https://api.graffiti.garden/classes/Graffiti.html#discover)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiDiscover}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the objects using {@link GraffitiObjectInfo} for debugging.\n */\nexport const GraffitiDiscover = Discover;\n/**\n * The [Graffiti.get](https://api.graffiti.garden/classes/Graffiti.html#get)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiGet}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the object using {@link GraffitiObjectInfo} for debugging.\n */\nexport const GraffitiGet = Get;\n/**\n * The [Graffiti.getMedia](https://api.graffiti.garden/classes/Graffiti.html#getmedia)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiGetMedia}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the media in an appropriate container based on its media type.\n */\nexport const GraffitiGetMedia = GetMedia;\n/**\n * The [Graffiti.actorToHandle](https://api.graffiti.garden/classes/Graffiti.html#actortohandle)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiActorToHandle}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the actor's handle.\n */\nexport const GraffitiActorToHandle = ActorToHandle;\n/**\n * The [Graffiti.handleToActor](https://api.graffiti.garden/classes/Graffiti.html#handletoactor)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiHandleToActor}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the actor DID.\n */\nexport const GraffitiHandleToActor = HandleToActor;\n/**\n * Displays a Graffiti object and all of its properties for\n * debugging purposes.\n */\nexport const GraffitiObjectInfo = ObjectInfo;\n"],"names":["o","t","e","globals","setGraffitiSession","session","setGraffitiSynchronize","synchronize","useGraffitiSynchronize","graffiti","useGraffiti","useGraffitiSession","useGraffitiDiscover","channels","schema","autopoll","objectsRaw","objects","ref","poll_","poll","isFirstPoll","syncIterator","discoverIterator","onScopeDispose","refresh","restartWatch","timeout","watch","toValue","args","_prev","onInvalidate","mySyncIterator","myDiscoverIterator","active","batchFlattenPromise","result","resolve","polling","continueFn","GraffitiErrorNotFound","value","useResolveString","input","output","resolved","err","displayOutput","useGraffitiActorToHandle","actor","props","__props","toRef","handle","_renderSlot","_ctx","_unref","_createElementVNode","_toDisplayString","deleting","deleteObject","object","_createElementBlock","_cache","_createVNode","ActorToHandle","_hoisted_3","_hoisted_2","_openBlock","_Fragment","_renderList","_hoisted_4","channel","_hoisted_5","$graffitiSession","_hoisted_6","$event","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_1","ObjectInfo","useGraffitiGet","url","iterator","myIterator","useGraffitiGetMedia","requirements","media","pollCounter","pollPromise","resolvePoll","data","allowed","dataUrl","downloadMedia","useGraffitiHandleToActor","GraffitiPlugin","app","options","graffitiBase","GraffitiSynchronize","graffitiSession","evt","detail","router","base","Discover","Get","GetMedia","HandleToActor","GraffitiDiscover","GraffitiGet","GraffitiGetMedia","GraffitiActorToHandle","GraffitiHandleToActor","GraffitiObjectInfo"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"plugin.js","sources":["../../node_modules/@graffiti-garden/api/dist/index.mjs","../../src/globals.ts","../../src/composables/discover.ts","../../src/composables/resolve-string.ts","../../src/composables/actor-to-handle.ts","../../src/components/ActorToHandle.vue","../../src/components/ObjectInfo.vue","../../src/components/Discover.vue","../../src/composables/get.ts","../../src/components/Get.vue","../../src/composables/get-media.ts","../../src/components/GetMedia.vue","../../src/composables/handle-to-actor.ts","../../src/components/HandleToActor.vue","../../src/plugin.ts"],"sourcesContent":["var n=class{};var u={type:\"object\",properties:{value:{type:\"object\"},channels:{type:\"array\",items:{type:\"string\"}},allowed:{type:\"array\",items:{type:\"string\"},nullable:!0},url:{type:\"string\"},actor:{type:\"string\"}},additionalProperties:!1,required:[\"value\",\"channels\",\"actor\",\"url\"]},b={...u,required:[\"value\",\"channels\"]};var c=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorForbidden\",Object.setPrototypeOf(this,t.prototype)}},f=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorNotFound\",Object.setPrototypeOf(this,t.prototype)}},m=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorInvalidSchema\",Object.setPrototypeOf(this,t.prototype)}},p=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorSchemaMismatch\",Object.setPrototypeOf(this,t.prototype)}},l=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorTooLarge\",Object.setPrototypeOf(this,t.prototype)}},S=class t extends Error{constructor(e){super(e),this.name=\"GraffitiErrorNotAcceptable\",Object.setPrototypeOf(this,t.prototype)}};function h(t){return typeof t==\"string\"?t:t.url}function y(t,e){return!Array.isArray(t.allowed)||typeof e?.actor==\"string\"&&(t.actor===e.actor||t.allowed.includes(e.actor))}function j(t,e,r){if(r===t.actor)return t;let a=t.allowed&&r?[r]:void 0,s=t.channels.filter(i=>e.includes(i));return{...t,allowed:a,channels:s}}function x(t,e){let[r,a]=t.toLowerCase().split(\";\")[0].split(\"/\");return!r||!a?!1:e.some(s=>{let[i,o]=s.toLowerCase().split(\";\")[0].split(\"/\");return!i||!o?!1:(i===r||i===\"*\")&&(o===a||o===\"*\")})}export{n as Graffiti,c as GraffitiErrorForbidden,m as GraffitiErrorInvalidSchema,S as GraffitiErrorNotAcceptable,f as GraffitiErrorNotFound,p as GraffitiErrorSchemaMismatch,l as GraffitiErrorTooLarge,u as GraffitiObjectJSONSchema,b as GraffitiPostObjectJSONSchema,y as isActorAllowedGraffitiObject,x as isMediaAcceptable,j as maskGraffitiObject,h as unpackObjectUrl};\n//# sourceMappingURL=index.mjs.map\n","import type { Ref } from \"vue\";\nimport type { Graffiti, GraffitiSession } from \"@graffiti-garden/api\";\nimport type { GraffitiSynchronize } from \"@graffiti-garden/wrapper-synchronize\";\n\nconst globals: {\n graffitiSynchronize?: GraffitiSynchronize;\n graffitiSession?: Ref<GraffitiSession | undefined | null>;\n} = {};\n\nexport function setGraffitiSession(\n session: Ref<GraffitiSession | undefined | null>,\n) {\n if (!globals.graffitiSession) {\n globals.graffitiSession = session;\n } else {\n throw new Error(\n \"Graffiti session already set - plugin installed multiple times?\",\n );\n }\n}\n\nexport function setGraffitiSynchronize(synchronize: GraffitiSynchronize) {\n if (!globals.graffitiSynchronize) {\n globals.graffitiSynchronize = synchronize;\n } else {\n throw new Error(\n \"Graffiti synchronize already set - plugin installed multiple times?\",\n );\n }\n}\n\n/**\n * Returns the global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance\n * that has been wrapped by the {@link GraffitiPlugin} with the [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html).\n * @throws If the {@link GraffitiPlugin} is not installed\n */\nexport function useGraffitiSynchronize() {\n const graffiti = globals.graffitiSynchronize;\n if (!graffiti) {\n throw new Error(\n \"No Graffiti instance provided, did you forget to install the plugin?\",\n );\n }\n return graffiti;\n}\n\n/**\n * Returns the global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance.\n *\n * In Vue templates and the [options API](https://vuejs.org/guide/introduction.html#options-api)\n * use may use the global variable {@link ComponentCustomProperties.$graffiti | $graffiti} instead.\n *\n * This is the same Graffiti registered with the {@link GraffitiPlugin}\n * via {@link GraffitiPluginOptions.graffiti}, only it has been wrapped\n * with [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html).\n * Be sure to use the wrapped instance to enable reactivity.\n *\n * @throws If the {@link GraffitiPlugin} is not installed\n */\nexport function useGraffiti(): Graffiti {\n return useGraffitiSynchronize();\n}\n\n/**\n * Returns a global reactive [GraffitiSession](https://api.graffiti.garden/interfaces/GraffitiSession.html) instance\n * as a [Vue ref](https://vuejs.org/api/reactivity-core.html#ref).\n *\n * In Vue templates and the [options API](https://vuejs.org/guide/introduction.html#options-api)\n * use the global variable {@link ComponentCustomProperties.$graffitiSession | $graffitiSession} instead.\n *\n * While the application is loading and restoring any previous sessions,\n * the value will be `undefined`. If the user is not logged in,\n * the value will be `null`.\n *\n * This only keeps track of one session. If your app needs\n * to support multiple login sessions, you'll need to manage them\n * yourself using [`Graffiti.sessionEvents`](https://api.graffiti.garden/classes/Graffiti.html#sessionevents).\n * @throws If the {@link GraffitiPlugin} is not installed\n */\nexport function useGraffitiSession() {\n const session = globals.graffitiSession;\n if (!session) {\n throw new Error(\n \"No Graffiti session provided, did you forget to install the plugin?\",\n );\n }\n return session;\n}\n","import type {\n GraffitiObject,\n GraffitiObjectStreamContinue,\n GraffitiObjectStreamContinueEntry,\n GraffitiObjectStreamError,\n GraffitiObjectStreamReturn,\n GraffitiSession,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter, Ref } from \"vue\";\nimport { ref, toValue, watch, onScopeDispose } from \"vue\";\nimport { useGraffitiSynchronize } from \"../globals\";\n\n/**\n * The [Graffiti.discover](https://api.graffiti.garden/classes/Graffiti.html#discover)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiDiscover}.\n *\n * The arguments of this composable are largely the same as Graffiti.discover,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * There is one additional optional argument `autopoll`, which when `true`,\n * will automatically poll for new objects.\n * As they change the arguments change, the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `objects`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * an array of Graffiti objects.\n * - `poll`: A function that can be called to manually check for objects.\n * - `isFirstPoll`: A boolean [ref](https://vuejs.org/api/reactivity-core.html#ref)\n * that indicates if the *first* poll after a change of arguments is currently running.\n * It may be used to show a loading spinner or disable a button, or it can be watched\n * to know when the `objects` array is ready to use.\n */\nexport function useGraffitiDiscover<Schema extends JSONSchema>(\n channels: MaybeRefOrGetter<string[]>,\n schema: MaybeRefOrGetter<Schema>,\n session?: MaybeRefOrGetter<GraffitiSession | undefined | null>,\n /**\n * Whether to automatically poll for new objects.\n */\n autopoll: MaybeRefOrGetter<boolean> = false,\n) {\n const graffiti = useGraffitiSynchronize();\n\n // Output\n const objectsRaw: Map<string, GraffitiObject<Schema>> = new Map();\n const objects: Ref<GraffitiObject<Schema>[]> = ref([]);\n let poll_ = async () => {};\n const poll = async () => poll_();\n const isFirstPoll = ref(true);\n\n // Maintain iterators for disposal\n let syncIterator: AsyncGenerator<GraffitiObjectStreamContinueEntry<Schema>>;\n let discoverIterator: GraffitiObjectStreamContinue<Schema>;\n onScopeDispose(() => {\n syncIterator?.return(null);\n discoverIterator?.return({\n continue: () => discoverIterator,\n cursor: \"\",\n });\n });\n\n const refresh = ref(0);\n function restartWatch(timeout = 0) {\n setTimeout(() => {\n refresh.value++;\n }, timeout);\n }\n watch(\n () => ({\n args: [toValue(channels), toValue(schema), toValue(session)] as const,\n refresh: refresh.value,\n }),\n ({ args }, _prev, onInvalidate) => {\n // Reset the output\n objectsRaw.clear();\n objects.value = [];\n isFirstPoll.value = true;\n\n // Initialize new iterators\n const mySyncIterator = graffiti.synchronizeDiscover<Schema>(...args);\n syncIterator = mySyncIterator;\n let myDiscoverIterator: GraffitiObjectStreamContinue<Schema>;\n\n // Set up automatic iterator cleanup\n let active = true;\n onInvalidate(() => {\n active = false;\n mySyncIterator.return(null);\n myDiscoverIterator?.return({\n continue: () => discoverIterator,\n cursor: \"\",\n });\n });\n\n // Start to synchronize in the background\n // (all polling results will go through here)\n let batchFlattenPromise: Promise<void> | undefined = undefined;\n (async () => {\n for await (const result of mySyncIterator) {\n if (!active) break;\n if (result.tombstone) {\n objectsRaw.delete(result.object.url);\n } else {\n objectsRaw.set(result.object.url, result.object);\n }\n // Flatten objects in batches to prevent\n // excessive re-rendering\n if (!batchFlattenPromise) {\n batchFlattenPromise = new Promise<void>((resolve) => {\n setTimeout(() => {\n if (active) {\n objects.value = Array.from(objectsRaw.values());\n }\n batchFlattenPromise = undefined;\n resolve();\n }, 50);\n });\n }\n }\n })();\n\n // Then set up a polling function\n let polling = false;\n let continueFn: GraffitiObjectStreamReturn<Schema>[\"continue\"] = () =>\n graffiti.discover<Schema>(...args);\n poll_ = async () => {\n if (polling || !active) return;\n polling = true;\n\n // Try to start the iterator\n try {\n myDiscoverIterator = continueFn(args[2]);\n } catch (e) {\n // Discovery is lazy so this should not happen,\n // wait a bit before retrying\n return restartWatch(5000);\n }\n if (!active) return;\n discoverIterator = myDiscoverIterator;\n\n while (true) {\n let result: IteratorResult<\n | GraffitiObjectStreamContinueEntry<Schema>\n | GraffitiObjectStreamError,\n GraffitiObjectStreamReturn<Schema>\n >;\n try {\n result = await myDiscoverIterator.next();\n } catch (e) {\n if (e instanceof GraffitiErrorNotFound) {\n // The cursor has expired, we need to start from scratch.\n return restartWatch();\n } else {\n // If something else went wrong, wait a bit before retrying\n return restartWatch(5000);\n }\n }\n if (!active) return;\n if (result.done) {\n continueFn = result.value.continue;\n break;\n } else if (result.value.error) {\n // Non-fatal errors do not stop the stream\n console.error(result.value.error);\n }\n }\n\n // Wait for sync to receive updates\n await new Promise((resolve) => setTimeout(resolve, 0));\n // And wait for pending results to be flattened\n if (batchFlattenPromise) await batchFlattenPromise;\n\n if (!active) return;\n polling = false;\n isFirstPoll.value = false;\n if (toValue(autopoll)) poll();\n };\n poll();\n },\n { immediate: true },\n );\n\n // Start polling if autopoll turns true\n watch(\n () => toValue(autopoll),\n (value) => value && poll(),\n );\n\n return {\n objects,\n poll,\n isFirstPoll,\n };\n}\n","import { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter } from \"vue\";\nimport { ref, toValue, watch } from \"vue\";\n\nexport function useResolveString(\n input: MaybeRefOrGetter<string>,\n resolve: (input: string) => Promise<string>,\n) {\n const output = ref<string | null | undefined>(undefined);\n\n watch(\n () => toValue(input),\n async (input, _prev, onInvalidate) => {\n let active = true;\n onInvalidate(() => {\n active = false;\n });\n\n output.value = undefined;\n\n try {\n const resolved = await resolve(input);\n if (active) output.value = resolved;\n } catch (err) {\n if (!active) return;\n\n if (err instanceof GraffitiErrorNotFound) {\n output.value = null;\n } else {\n console.error(err);\n }\n }\n },\n { immediate: true },\n );\n\n return {\n output,\n };\n}\n\nexport function displayOutput(output: string | null | undefined) {\n if (output === undefined) return \"Loading...\";\n if (output === null) return \"Not found\";\n return output;\n}\n","import type { MaybeRefOrGetter } from \"vue\";\nimport { useGraffiti } from \"../globals\";\nimport { useResolveString } from \"./resolve-string\";\n\n/**\n * The [Graffiti.actorToHandle](https://api.graffiti.garden/classes/Graffiti.html#actortohandle)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiActorToHandle}.\n *\n * The arguments of this composable are the same as Graffiti.actorToHandle,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `handle`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved handle, if it exists. If the handle cannot be found, the result\n * is `null`. If the handle is still being fetched, the result is `undefined`.\n */\nexport function useGraffitiActorToHandle(actor: MaybeRefOrGetter<string>) {\n const graffiti = useGraffiti();\n const { output } = useResolveString(\n actor,\n graffiti.actorToHandle.bind(graffiti),\n );\n return { handle: output };\n}\n","<script setup lang=\"ts\">\nimport { toRef } from \"vue\";\nimport { displayOutput } from \"../composables/resolve-string\";\nimport { useGraffitiActorToHandle } from \"../composables/actor-to-handle\";\n\nconst props = defineProps<{ actor: string }>();\nconst actor = toRef(props, \"actor\");\n\nconst { handle } = useGraffitiActorToHandle(actor);\n</script>\n\n<template>\n <slot :handle=\"handle\">\n <span> {{ displayOutput(handle) }} </span>\n </slot>\n</template>\n","<script setup lang=\"ts\">\nimport type { GraffitiObjectBase, GraffitiSession } from \"@graffiti-garden/api\";\nimport ActorToHandle from \"./ActorToHandle.vue\";\nimport { useGraffiti } from \"../globals\";\nimport { ref } from \"vue\";\n\ndefineProps<{\n object: GraffitiObjectBase | null | undefined;\n}>();\n\nconst graffiti = useGraffiti();\nconst deleting = ref(false);\nasync function deleteObject(\n object: GraffitiObjectBase,\n session: GraffitiSession,\n) {\n deleting.value = true;\n await new Promise((resolve) => setTimeout(resolve, 0));\n if (\n confirm(\n \"Are you sure you want to delete this object? It cannot be undone.\",\n )\n ) {\n await graffiti.delete(object, session);\n }\n deleting.value = false;\n}\n</script>\n\n<template>\n <article v-if=\"object\" :data-url=\"object.url\">\n <header>\n <h2>Graffiti Object</h2>\n\n <dl>\n <dt>Object URL</dt>\n <dd>\n <code>{{ object.url }}</code>\n </dd>\n\n <dt>Actor</dt>\n <dd>\n <code>{{ object.actor }}</code>\n </dd>\n\n <dt>Handle</dt>\n <dd>\n <ActorToHandle :actor=\"object.actor\" />\n </dd>\n </dl>\n </header>\n\n <section>\n <h3>Content</h3>\n <pre>{{ object.value }}</pre>\n </section>\n\n <section>\n <h3>Allowed Actors</h3>\n\n <p v-if=\"!Array.isArray(object.allowed)\">\n <em>Public</em>\n </p>\n <p v-else-if=\"object.allowed.length === 0\">\n <em>Noone</em>\n </p>\n <ul>\n <li v-for=\"actor in object.allowed\" :key=\"actor\">\n <dl>\n <dt>Actor</dt>\n <dd>\n <code>{{ actor }}</code>\n </dd>\n <dt>Handle</dt>\n <dd>\n <ActorToHandle :actor=\"actor\" />\n </dd>\n </dl>\n </li>\n </ul>\n </section>\n\n <section>\n <h3>Channels</h3>\n\n <ul v-if=\"object.channels?.length\">\n <li v-for=\"channel in object.channels\" :key=\"channel\">\n <code>{{ channel }}</code>\n </li>\n </ul>\n <p v-else>\n <em>No channels</em>\n </p>\n </section>\n\n <footer>\n <nav>\n <ul>\n <li v-if=\"$graffitiSession.value?.actor === object.actor\">\n <button\n :disabled=\"deleting\"\n @click=\"\n deleteObject(object, $graffitiSession.value)\n \"\n >\n {{ deleting ? \"Deleting...\" : \"Delete\" }}\n </button>\n </li>\n </ul>\n </nav>\n </footer>\n </article>\n\n <article v-else-if=\"object === null\">\n <header>\n <h2>Graffiti Object</h2>\n </header>\n <p><em>Object not found</em></p>\n </article>\n\n <article v-else>\n <header>\n <h2>Graffiti Object</h2>\n </header>\n <p><em>Loading...</em></p>\n </article>\n</template>\n","<script setup lang=\"ts\" generic=\"Schema extends JSONSchema\">\nimport { toRef } from \"vue\";\nimport type {\n GraffitiSession,\n JSONSchema,\n GraffitiObject,\n} from \"@graffiti-garden/api\";\nimport { useGraffitiDiscover } from \"../composables/discover\";\nimport ObjectInfo from \"./ObjectInfo.vue\";\n\nconst props = defineProps<{\n channels: string[];\n schema: Schema;\n session?: GraffitiSession | null;\n autopoll?: boolean;\n}>();\n\ndefineSlots<{\n default?(props: {\n objects: GraffitiObject<Schema>[];\n poll: () => Promise<void>;\n isFirstPoll: boolean;\n }): any;\n}>();\n\nconst { objects, poll, isFirstPoll } = useGraffitiDiscover<Schema>(\n toRef(props, \"channels\"),\n toRef(props, \"schema\"),\n toRef(props, \"session\"),\n toRef(props, \"autopoll\"),\n);\n</script>\n\n<template>\n <slot :objects=\"objects\" :poll=\"poll\" :isFirstPoll=\"isFirstPoll\">\n <ul v-if=\"!isFirstPoll\">\n <li v-for=\"object in objects\" :key=\"object.url\">\n <ObjectInfo :object=\"object\" />\n </li>\n </ul>\n <p v-else>\n <em> Loading... </em>\n </p>\n </slot>\n</template>\n","import type {\n GraffitiObject,\n GraffitiObjectUrl,\n GraffitiObjectStreamContinueEntry,\n GraffitiSession,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter, Ref } from \"vue\";\nimport { ref, toValue, watch, onScopeDispose } from \"vue\";\nimport { useGraffitiSynchronize } from \"../globals\";\n\n/**\n * The [Graffiti.get](https://api.graffiti.garden/classes/Graffiti.html#get)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiGet}.\n *\n * The arguments of this composable are the same as Graffiti.get,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `object`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved Graffiti object, if it exists. If the object cannot be found,\n * the result is `null`. If the object is still being fetched, the result is `undefined`.\n * - `poll`: A function that can be called to manually check if the object has changed.\n */\nexport function useGraffitiGet<Schema extends JSONSchema>(\n url: MaybeRefOrGetter<GraffitiObjectUrl | string>,\n schema: MaybeRefOrGetter<Schema>,\n session?: MaybeRefOrGetter<GraffitiSession | undefined | null>,\n): {\n object: Ref<GraffitiObject<Schema> | null | undefined>;\n poll: () => Promise<void>;\n} {\n const graffiti = useGraffitiSynchronize();\n\n const object: Ref<GraffitiObject<Schema> | null | undefined> = ref(undefined);\n let poll_ = async () => {};\n const poll = async () => poll_();\n\n let iterator: AsyncGenerator<GraffitiObjectStreamContinueEntry<Schema>>;\n onScopeDispose(() => {\n iterator?.return(null);\n });\n\n watch(\n () => [toValue(url), toValue(schema), toValue(session)] as const,\n (args, _prev, onInvalidate) => {\n // Reset the object value (undefined = \"loading\")\n object.value = undefined;\n\n // Initialize a new iterator\n const myIterator = graffiti.synchronizeGet<Schema>(...args);\n iterator = myIterator;\n\n // Make sure to dispose of the iterator when invalidated\n let active = true;\n onInvalidate(() => {\n active = false;\n myIterator.return(null);\n });\n\n // Listen to the iterator in the background,\n // it will receive results from polling below\n (async () => {\n for await (const result of myIterator) {\n if (!active) return;\n if (result.tombstone) {\n object.value = null;\n } else {\n object.value = result.object;\n }\n }\n })();\n\n // Then set up a polling function\n let polling = false;\n poll_ = async () => {\n if (polling || !active) return;\n polling = true;\n try {\n await graffiti.get<Schema>(...args);\n } catch (e) {\n if (!(e instanceof GraffitiErrorNotFound)) {\n console.error(e);\n }\n }\n\n // Wait for sync to receive the update\n await new Promise((resolve) => setTimeout(resolve, 0));\n polling = false;\n };\n poll();\n },\n { immediate: true },\n );\n\n return {\n object,\n poll,\n };\n}\n","<script setup lang=\"ts\" generic=\"Schema extends JSONSchema\">\nimport { toRef } from \"vue\";\nimport type {\n GraffitiObjectUrl,\n GraffitiObject,\n GraffitiSession,\n JSONSchema,\n} from \"@graffiti-garden/api\";\nimport { useGraffitiGet } from \"../composables/get\";\nimport ObjectInfo from \"./ObjectInfo.vue\";\n\nconst props = defineProps<{\n url: string | GraffitiObjectUrl;\n schema: Schema;\n session?: GraffitiSession | null;\n}>();\n\ndefineSlots<{\n default?(props: {\n object: GraffitiObject<Schema> | undefined | null;\n poll: () => Promise<void>;\n }): any;\n}>();\n\nconst { object, poll } = useGraffitiGet<Schema>(\n toRef(props, \"url\"),\n toRef(props, \"schema\"),\n toRef(props, \"session\"),\n);\n</script>\n\n<template>\n <slot :object=\"object\" :poll=\"poll\">\n <ObjectInfo :object=\"object\" />\n </slot>\n</template>\n","import type {\n GraffitiMedia,\n GraffitiMediaAccept,\n GraffitiSession,\n} from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport type { MaybeRefOrGetter, Ref } from \"vue\";\nimport { ref, toValue, watch, onScopeDispose } from \"vue\";\nimport { useGraffitiSynchronize } from \"../globals\";\n\n/**\n * The [Graffiti.getMedia](https://api.graffiti.garden/classes/Graffiti.html#getMedia)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiGetMedia}.\n *\n * The arguments of this composable are the same as Graffiti.getMedia,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `media`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved Graffiti media, if it exists. The media will include a `dataUrl` property\n * that can be used to directly display the media in a template. If the media has been deleted,\n * the result is `null`. If the media is still being fetched, the result is `undefined`.\n * - `poll`: A function that can be called to manually check if the media has changed.\n */\nexport function useGraffitiGetMedia(\n url: MaybeRefOrGetter<string>,\n accept: MaybeRefOrGetter<GraffitiMediaAccept>,\n session?: MaybeRefOrGetter<GraffitiSession | undefined | null>,\n): {\n media: Ref<(GraffitiMedia & { dataUrl: string }) | null | undefined>;\n poll: () => Promise<void>;\n} {\n const graffiti = useGraffitiSynchronize();\n const media = ref<(GraffitiMedia & { dataUrl: string }) | null | undefined>(\n undefined,\n );\n\n // The \"poll counter\" is a hack to get\n // watch to refresh\n const pollCounter = ref(0);\n let pollPromise: Promise<void> | null = null;\n let resolvePoll = () => {};\n function poll() {\n if (pollPromise) return pollPromise;\n pollCounter.value++;\n // Wait until the watch finishes and calls\n // \"pollResolve\" to finish the poll\n pollPromise = new Promise<void>((resolve) => {\n resolvePoll = () => {\n pollPromise = null;\n resolve();\n };\n });\n return pollPromise;\n }\n watch(\n () => ({\n args: [toValue(url), toValue(accept), toValue(session)] as const,\n pollCounter: pollCounter.value,\n }),\n async ({ args }, _prev, onInvalidate) => {\n // Revoke the data URL to prevent a memory leak\n if (media.value?.dataUrl) {\n URL.revokeObjectURL(media.value.dataUrl);\n }\n media.value = undefined;\n\n let active = true;\n onInvalidate(() => {\n active = false;\n });\n\n try {\n const { data, actor, allowed } = await graffiti.getMedia(...args);\n if (!active) return;\n const dataUrl = URL.createObjectURL(data);\n media.value = {\n data,\n dataUrl,\n actor,\n allowed,\n };\n } catch (e) {\n if (!active) return;\n if (e instanceof GraffitiErrorNotFound) {\n media.value = null;\n } else {\n console.error(e);\n }\n } finally {\n resolvePoll();\n }\n },\n { immediate: true },\n );\n\n onScopeDispose(() => {\n resolvePoll();\n if (media.value?.dataUrl) {\n URL.revokeObjectURL(media.value.dataUrl);\n }\n });\n\n return {\n media,\n poll,\n };\n}\n","<script setup lang=\"ts\">\nimport { toRef } from \"vue\";\nimport type {\n GraffitiSession,\n GraffitiMediaAccept,\n GraffitiMedia,\n} from \"@graffiti-garden/api\";\nimport { useGraffitiGetMedia } from \"../composables/get-media\";\n\nconst props = defineProps<{\n url: string;\n accept: GraffitiMediaAccept;\n session?: GraffitiSession | null;\n}>();\n\ndefineSlots<{\n default?(props: {\n media: (GraffitiMedia & { dataUrl: string }) | null | undefined;\n poll: () => Promise<void>;\n }): any;\n}>();\n\nconst { media, poll } = useGraffitiGetMedia(\n toRef(props, \"url\"),\n toRef(props, \"accept\"),\n toRef(props, \"session\"),\n);\n\nfunction downloadMedia() {\n if (media.value) {\n window.location.href = media.value.dataUrl;\n }\n}\n</script>\n\n<template>\n <slot :media=\"media\" :poll=\"poll\">\n <img\n v-if=\"media?.data.type.startsWith('image/')\"\n :src=\"media.dataUrl\"\n :alt=\"`An image by ${media.actor}`\"\n />\n <video\n v-else-if=\"media?.data.type.startsWith('video/')\"\n controls\n :src=\"media.dataUrl\"\n :alt=\"`A video by ${media.actor}`\"\n />\n <audio\n v-else-if=\"media?.data.type.startsWith('audio/')\"\n controls\n :src=\"media.dataUrl\"\n :alt=\"`Audio by ${media.actor}`\"\n />\n <iframe\n v-else-if=\"media?.data.type === 'text/html'\"\n :src=\"media.dataUrl\"\n :alt=\"`HTML by ${media.actor}`\"\n sandbox=\"\"\n />\n <object\n v-else-if=\"media?.data.type.startsWith('application/pdf')\"\n :data=\"media.dataUrl\"\n type=\"application/pdf\"\n :alt=\"`PDF by ${media.actor}`\"\n />\n <button v-else-if=\"media\" @click=\"downloadMedia\">Download</button>\n <p v-else-if=\"media === null\">\n <em>Media not found</em>\n </p>\n <p v-else>\n <em> Loading... </em>\n </p>\n </slot>\n</template>\n","import type { MaybeRefOrGetter } from \"vue\";\nimport { useGraffiti } from \"../globals\";\nimport { useResolveString } from \"./resolve-string\";\n\n/**\n * The [Graffiti.handleToActor](https://api.graffiti.garden/classes/Graffiti.html#handletoactor)\n * method as a reactive [composable](https://vuejs.org/guide/reusability/composables.html)\n * for use in the Vue [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * Its corresponding renderless component is {@link GraffitiHandleToActor}.\n *\n * The arguments of this composable are the same as Graffiti.handleToActor,\n * only they can also be [Refs](https://vuejs.org/api/reactivity-core.html#ref)\n * or [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description).\n * As they change the output will automatically update.\n * Reactivity only triggers when the root array or object changes,\n * not when the elements or properties change.\n * If you need deep reactivity, wrap your argument in a getter.\n *\n * @returns\n * - `actor`: A [ref](https://vuejs.org/api/reactivity-core.html#ref) that contains\n * the retrieved actor, if it exists. If the actor cannot be found, the result\n * is `null`. If the actor is still being fetched, the result is `undefined`.\n */\nexport function useGraffitiHandleToActor(handle: MaybeRefOrGetter<string>) {\n const graffiti = useGraffiti();\n const { output } = useResolveString(\n handle,\n graffiti.handleToActor.bind(graffiti),\n );\n return { actor: output };\n}\n","<script setup lang=\"ts\">\nimport { toRef } from \"vue\";\nimport { displayOutput } from \"../composables/resolve-string\";\nimport { useGraffitiHandleToActor } from \"../composables/handle-to-actor\";\n\nconst props = defineProps<{ handle: string }>();\nconst handle = toRef(props, \"handle\");\n\nconst { actor } = useGraffitiHandleToActor(handle);\n</script>\n\n<template>\n <slot :actor=\"actor\">\n <span> {{ displayOutput(actor) }} </span>\n </slot>\n</template>\n","import type { App, Plugin, Ref } from \"vue\";\nimport { ref } from \"vue\";\nimport Discover from \"./components/Discover.vue\";\nimport Get from \"./components/Get.vue\";\nimport GetMedia from \"./components/GetMedia.vue\";\nimport ActorToHandle from \"./components/ActorToHandle.vue\";\nimport HandleToActor from \"./components/HandleToActor.vue\";\nimport ObjectInfo from \"./components/ObjectInfo.vue\";\nimport type {\n Graffiti,\n GraffitiSession,\n GraffitiLoginEvent,\n GraffitiLogoutEvent,\n GraffitiSessionInitializedEvent,\n} from \"@graffiti-garden/api\";\nimport { setGraffitiSession, setGraffitiSynchronize } from \"./globals\";\nimport type { Router } from \"vue-router\";\nimport { GraffitiSynchronize } from \"@graffiti-garden/wrapper-synchronize\";\n\ndeclare module \"vue\" {\n export interface ComponentCustomProperties {\n /**\n * Global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance.\n *\n * In the [composition API](https://vuejs.org/guide/introduction.html#composition-api)\n * use {@link useGraffiti} instead.\n *\n * This is the same Graffiti registered with the {@link GraffitiPlugin}\n * via {@link GraffitiPluginOptions.graffiti}, only it has been wrapped\n * with [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html).\n * Be sure to use the wrapped instance to enable reactivity.\n */\n $graffiti: Graffiti;\n /**\n * Global reactive [GraffitiSession](https://api.graffiti.garden/classes/GraffitiSession.html) instance\n * as a [Vue ref](https://vuejs.org/api/reactivity-core.html#ref).\n *\n * In the [composition API](https://vuejs.org/guide/introduction.html#composition-api)\n * use {@link useGraffitiSession} instead.\n *\n * While the application is loading and restoring any previous sessions,\n * the value will be `undefined`. If the user is not logged in,\n * the value will be `null`.\n *\n * This only keeps track of one session. If your app needs\n * to support multiple login sessions, you'll need to manage them\n * yourself using [`Graffiti.sessionEvents`](https://api.graffiti.garden/classes/Graffiti.html#sessionevents).\n */\n $graffitiSession: Ref<GraffitiSession | undefined | null>;\n }\n\n export interface GlobalComponents {\n GraffitiDiscover: typeof Discover;\n GraffitiGet: typeof Get;\n GraffitiGetMedia: typeof GetMedia;\n GraffitiActorToHandle: typeof ActorToHandle;\n GraffitiHandleToActor: typeof HandleToActor;\n GraffitiObjectInfo: typeof ObjectInfo;\n }\n}\nexport type { ComponentCustomProperties } from \"vue\";\n\n/**\n * Options for the {@link GraffitiPlugin}.\n */\nexport interface GraffitiPluginOptions {\n /**\n * An instance of the [Graffiti API](https://api.graffiti.garden/classes/Graffiti.html)\n * for the Vue.js plugin to use.\n * This instance, wrapped with [GraffitiSynchronize](https://sync.graffiti.garden/classes/GraffitiSynchronize.html),\n * will be exposed in Vue templates as {@link ComponentCustomProperties.$graffiti | $graffiti}\n * and in setup functions as {@link useGraffiti}.\n * You must interact with Graffiti through these wrapped instances\n * to enable reactivity.\n */\n graffiti: Graffiti;\n}\n\n/**\n * A [Vue.js](https://vuejs.org/) plugin that wraps around\n * the [Graffiti API](https://api.graffiti.garden/classes/Graffiti.html)\n * to provide [reactive](https://en.wikipedia.org/wiki/Reactive_programming) versions\n * of various Graffiti API methods.\n *\n * These reactive methods are available as both\n * [renderless components](https://vuejs.org/guide/components/slots#renderless-components),\n * which make it possible to create a whole Graffiti app in an HTML template,\n * and [composables](https://vuejs.org/guide/reusability/composables.html),\n * which can be used in the programmatic [composition API](https://vuejs.org/guide/introduction.html#composition-api).\n *\n * | [API](https://api.graffiti.garden/classes/Graffiti.html) method | [Composable](https://vuejs.org/guide/reusability/composables.html) | [Component](https://vuejs.org/guide/components/slots#renderless-components) |\n * | --- | --- | --- |\n * | [discover](https://api.graffiti.garden/classes/Graffiti.html#discover) | {@link useGraffitiDiscover} | {@link GraffitiDiscover} |\n * | [get](https://api.graffiti.garden/classes/Graffiti.html#get) | {@link useGraffitiGet} | {@link GraffitiGet} |\n * | [getMedia](https://api.graffiti.garden/classes/Graffiti.html#getmedia) | {@link useGraffitiGetMedia} | {@link GraffitiGetMedia} |\n * | [actorToHandle](https://api.graffiti.garden/classes/Graffiti.html#actortohandle) | {@link useGraffitiActorToHandle} | {@link GraffitiActorToHandle} |\n * | [handleToActor](https://api.graffiti.garden/classes/Graffiti.html#handletoactor) | {@link useGraffitiHandleToActor} | {@link GraffitiHandleToActor} |\n *\n * The plugin also exposes a global [Graffiti](https://api.graffiti.garden/classes/Graffiti.html) instance\n * and keeps track of the global [GraffitiSession](https://api.graffiti.garden/interfaces/GraffitiSession.html)\n * state as a reactive variable.\n * They are available in templates as global variables or in setup functions as\n * getter functions.\n *\n * | Global variabale | Getter |\n * | --- | --- |\n * | {@link ComponentCustomProperties.$graffiti | $graffiti } | {@link useGraffiti} |\n * | {@link ComponentCustomProperties.$graffitiSession | $graffitiSession } | {@link useGraffitiSession} |\n *\n * Finally, the plugin exposes an additional component, {@link GraffitiObjectInfo}\n * that can be use to generically display a Graffiti object for debugging purposes.\n * {@link GraffitiDiscover} and {@link GraffitiGet} show this output as\n * [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * if no template is provided\n *\n * [See the README for installation instructions](/).\n *\n * You can [try out live examples](/examples/), but basic usage looks like this:\n *\n * ```ts\n * import { createApp } from \"vue\";\n * import { GraffitiPlugin } from \"@graffiti-garden/vue\";\n * import { GraffitiLocal } from \"@graffiti-garden/implementation-local\";\n * import App from \"./App.vue\";\n *\n * createApp(App)\n * .use(GraffitiPlugin, {\n * graffiti: new GraffitiLocal(),\n * })\n * ```\n *\n * ```vue\n * <!-- App.vue -->\n * <template>\n * <button\n * v-if=\"$graffitiSession.value\"\n * @click=\"$graffiti.post({\n * value: { content: 'Hello, world!' },\n * channels: [ 'my-channel' ]\n * }, $graffitiSession.value)\"\n * >\n * Say Hello\n * </button>\n * <button v-else @click=\"$graffiti.login()\">\n * Log In to Say Hello\n * </button>\n *\n * <GraffitiDiscover\n * v-slot=\"{ objects }\"\n * :channels=\"[ 'my-channel' ]\"\n * :schema=\"{\n * properties: {\n * value: {\n * required: ['content'],\n * properties: {\n * content: { type: 'string' }\n * }\n * }\n * }\n * }\"\n * >\n * <ul>\n * <li\n * v-for=\"object in objects\"\n * :key=\"object.url\"\n * >\n * {{ object.value.content }}\n * </li>\n * </ul>\n * </GraffitiDiscover>\n * </template>\n * ```\n */\nexport const GraffitiPlugin: Plugin<GraffitiPluginOptions> = {\n install(app: App, options: GraffitiPluginOptions) {\n const graffitiBase = options.graffiti;\n const graffiti = new GraffitiSynchronize(graffitiBase);\n\n const graffitiSession = ref<GraffitiSession | undefined | null>(undefined);\n graffiti.sessionEvents.addEventListener(\"initialized\", async (evt) => {\n const detail = (evt as GraffitiSessionInitializedEvent).detail;\n\n if (detail && detail.error) {\n console.error(detail.error);\n }\n\n if (detail && detail.href) {\n // If we're using Vue Router, redirect to the URL after login\n const router = app.config.globalProperties.$router as\n | Router\n | undefined;\n if (router) {\n const base = router.options.history.base;\n const url = new URL(detail.href);\n if (url.pathname.startsWith(base)) {\n url.pathname = url.pathname.slice(base.length);\n }\n await router.replace(url.pathname + url.search + url.hash);\n }\n }\n\n // Set the session to \"null\" if the user is not logged in\n if (!graffitiSession.value) {\n graffitiSession.value = null;\n }\n });\n graffiti.sessionEvents.addEventListener(\"login\", (evt) => {\n const detail = (evt as GraffitiLoginEvent).detail;\n if (detail.error) {\n console.error(\"Error logging in:\");\n console.error(detail.error);\n return;\n } else {\n graffitiSession.value = detail.session;\n }\n });\n graffiti.sessionEvents.addEventListener(\"logout\", (evt) => {\n const detail = (evt as GraffitiLogoutEvent).detail;\n if (detail.error) {\n console.error(\"Error logging out:\");\n console.error(detail.error);\n } else {\n graffitiSession.value = null;\n }\n });\n\n setGraffitiSynchronize(graffiti);\n setGraffitiSession(graffitiSession);\n\n app.component(\"GraffitiDiscover\", Discover);\n app.component(\"GraffitiGet\", Get);\n app.component(\"GraffitiGetMedia\", GetMedia);\n app.component(\"GraffitiActorToHandle\", ActorToHandle);\n app.component(\"GraffitiHandleToActor\", HandleToActor);\n app.component(\"GraffitiObjectInfo\", ObjectInfo);\n app.config.globalProperties.$graffiti = graffiti;\n app.config.globalProperties.$graffitiSession = graffitiSession;\n },\n};\n\nexport { useGraffitiActorToHandle } from \"./composables/actor-to-handle\";\nexport { useGraffitiHandleToActor } from \"./composables/handle-to-actor\";\nexport { useGraffitiDiscover } from \"./composables/discover\";\nexport { useGraffitiGet } from \"./composables/get\";\nexport { useGraffitiGetMedia } from \"./composables/get-media\";\nexport {\n useGraffiti,\n useGraffitiSynchronize,\n useGraffitiSession,\n} from \"./globals\";\n\n/**\n * The [Graffiti.discover](https://api.graffiti.garden/classes/Graffiti.html#discover)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiDiscover}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the objects using {@link GraffitiObjectInfo} for debugging.\n */\nexport const GraffitiDiscover = Discover;\n/**\n * The [Graffiti.get](https://api.graffiti.garden/classes/Graffiti.html#get)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiGet}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the object using {@link GraffitiObjectInfo} for debugging.\n */\nexport const GraffitiGet = Get;\n/**\n * The [Graffiti.getMedia](https://api.graffiti.garden/classes/Graffiti.html#getmedia)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiGetMedia}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the media in an appropriate container based on its media type.\n */\nexport const GraffitiGetMedia = GetMedia;\n/**\n * The [Graffiti.actorToHandle](https://api.graffiti.garden/classes/Graffiti.html#actortohandle)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiActorToHandle}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the actor's handle.\n */\nexport const GraffitiActorToHandle = ActorToHandle;\n/**\n * The [Graffiti.handleToActor](https://api.graffiti.garden/classes/Graffiti.html#handletoactor)\n * method as a reactive [renderless component](https://vuejs.org/guide/components/slots#renderless-components)\n * for use in Vue templates.\n *\n * Its props and [slots props](https://vuejs.org/guide/components/slots.html#scoped-slots)\n * are identical to the arguments and return values of\n * the composable {@link useGraffitiHandleToActor}. If no template is provided to\n * the default slot, [fallback content](https://vuejs.org/guide/components/slots.html#fallback-content)\n * will display the actor DID.\n */\nexport const GraffitiHandleToActor = HandleToActor;\n/**\n * Displays a Graffiti object and all of its properties for\n * debugging purposes.\n */\nexport const GraffitiObjectInfo = ObjectInfo;\n"],"names":["f","t","e","globals","setGraffitiSession","session","setGraffitiSynchronize","synchronize","useGraffitiSynchronize","graffiti","useGraffiti","useGraffitiSession","useGraffitiDiscover","channels","schema","autopoll","objectsRaw","objects","ref","poll_","poll","isFirstPoll","syncIterator","discoverIterator","onScopeDispose","refresh","restartWatch","timeout","watch","toValue","args","_prev","onInvalidate","mySyncIterator","myDiscoverIterator","active","batchFlattenPromise","result","resolve","polling","continueFn","GraffitiErrorNotFound","value","useResolveString","input","output","resolved","err","displayOutput","useGraffitiActorToHandle","actor","props","__props","toRef","handle","_renderSlot","_ctx","_unref","_createElementVNode","_toDisplayString","deleting","deleteObject","object","_createElementBlock","_cache","_createVNode","ActorToHandle","_hoisted_3","_hoisted_2","_openBlock","_Fragment","_renderList","_hoisted_4","channel","_hoisted_5","$graffitiSession","_hoisted_6","$event","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_1","ObjectInfo","useGraffitiGet","url","iterator","myIterator","useGraffitiGetMedia","accept","media","pollCounter","pollPromise","resolvePoll","data","allowed","dataUrl","downloadMedia","useGraffitiHandleToActor","GraffitiPlugin","app","options","graffitiBase","GraffitiSynchronize","graffitiSession","evt","detail","router","base","Discover","Get","GetMedia","HandleToActor","GraffitiDiscover","GraffitiGet","GraffitiGetMedia","GraffitiActorToHandle","GraffitiHandleToActor","GraffitiObjectInfo"],"mappings":"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","x_google_ignoreList":[0]}