From cfd56f54399fbc3b65a746ac6022519f409a9b0b Mon Sep 17 00:00:00 2001 From: freshgum <85623267+freshgum-bubbles@users.noreply.github.com> Date: Fri, 4 Aug 2023 21:33:47 +0100 Subject: [PATCH] Deploy website - based on adb6b8061ccbda0028be6ba0f9c9a8bc08d56efa --- 404.html | 12 ++++---- assets/js/0e88606a.5b195619.js | 1 + assets/js/0e88606a.c0cb7e70.js | 1 - assets/js/1c20f44b.bb83176f.js | 1 + assets/js/1c20f44b.c2dd1418.js | 1 - assets/js/1df93b7f.0e81d588.js | 1 - assets/js/1df93b7f.5cf77e22.js | 1 + assets/js/21.9ddbf3f4.js | 1 - assets/js/21c3df7e.50db2763.js | 1 + assets/js/21c3df7e.d6eeaef8.js | 1 - ...1cf83.d7459cdf.js => 3021cf83.3c388bdd.js} | 2 +- ...4719e.e92460df.js => 3334719e.ef315589.js} | 2 +- assets/js/37e83d0a.b9c42019.js | 1 + assets/js/37e83d0a.df8013bf.js | 1 - ...be207.6c4a0910.js => 393be207.579ed0c1.js} | 2 +- assets/js/3e3bd4e4.3abddf15.js | 1 - assets/js/3e3bd4e4.c1ead911.js | 1 + assets/js/3f288906.aae31196.js | 1 + assets/js/3f288906.c4742133.js | 1 - assets/js/45395bfd.0c0531e4.js | 1 - assets/js/45395bfd.e0a879e0.js | 1 + assets/js/520.6480633a.js | 1 + assets/js/531df37a.87b69254.js | 1 - assets/js/531df37a.d0a2f7b8.js | 1 + assets/js/6913d2c8.3d3ea882.js | 1 + assets/js/6913d2c8.ea6cb356.js | 1 - ...40a3c.3cf290c5.js => 72140a3c.6899ebb8.js} | 2 +- ...1c5db.727eea00.js => 7281c5db.d4799824.js} | 2 +- assets/js/8167aad2.4f6a095b.js | 1 - assets/js/8167aad2.cf954963.js | 1 + assets/js/89113871.2ac48097.js | 1 - assets/js/89113871.c9befc60.js | 1 + assets/js/935f2afb.21b271de.js | 1 - assets/js/935f2afb.b89b4ba2.js | 1 + assets/js/9d628f83.1eb64dad.js | 1 + assets/js/9d628f83.894c32a1.js | 1 - assets/js/a8b2a833.0897f0d6.js | 1 + assets/js/a8b2a833.a681ab19.js | 1 - assets/js/b27c2848.993481cc.js | 1 - assets/js/b27c2848.b50282bd.js | 1 + assets/js/bdef968a.17f76d20.js | 1 - assets/js/bdef968a.951df9ba.js | 1 + assets/js/d10e8d20.7fb672e0.js | 1 - assets/js/d10e8d20.e9d8a91e.js | 1 + assets/js/dde0a8be.8807e4a0.js | 1 + assets/js/dde0a8be.e14f11c5.js | 1 - assets/js/eb1ab973.0f5c4678.js | 1 + assets/js/eb1ab973.4ae66d14.js | 1 - assets/js/main.02395a04.js | 2 -- assets/js/main.205ef86e.js | 2 ++ ...CENSE.txt => main.205ef86e.js.LICENSE.txt} | 0 assets/js/runtime~main.0873ad78.js | 1 - assets/js/runtime~main.ab27205f.js | 1 + docs/examples/hello-world/index.html | 20 ++++++------- .../application-disposal/index.html | 14 ++++----- .../implementation/index.html | 20 ++++++------- .../nodejs-web-server/testing/index.html | 14 ++++----- docs/getting-started/index.html | 14 ++++----- .../containers/creating-containers/index.html | 30 +++++++++---------- .../containers/custom-containers/index.html | 16 +++++----- docs/guide/containers/introduction/index.html | 26 ++++++++-------- docs/guide/react/introduction/index.html | 14 ++++----- docs/guide/services/eager-services/index.html | 20 ++++++------- docs/guide/services/host-container/index.html | 14 ++++----- docs/guide/services/introduction/index.html | 24 +++++++-------- .../services/multiple-services/index.html | 18 +++++------ .../resolution-constraints/index.html | 20 ++++++------- docs/guide/services/singletons/index.html | 16 +++++----- .../services/transient-services/index.html | 22 +++++++------- .../services/usage-in-javascript/index.html | 20 ++++++------- docs/guide/tokens/introduction/index.html | 20 ++++++------- docs/meta/code-of-conduct/index.html | 14 ++++----- docs/meta/contributing/index.html | 12 ++++---- docs/meta/license/index.html | 12 ++++---- .../migrating-from-upstream-typedi/index.html | 12 ++++---- index.html | 12 ++++---- markdown-page/index.html | 12 ++++---- search-index.json | 2 +- search/index.html | 12 ++++---- sitemap.xml | 2 +- 80 files changed, 251 insertions(+), 251 deletions(-) create mode 100644 assets/js/0e88606a.5b195619.js delete mode 100644 assets/js/0e88606a.c0cb7e70.js create mode 100644 assets/js/1c20f44b.bb83176f.js delete mode 100644 assets/js/1c20f44b.c2dd1418.js delete mode 100644 assets/js/1df93b7f.0e81d588.js create mode 100644 assets/js/1df93b7f.5cf77e22.js delete mode 100644 assets/js/21.9ddbf3f4.js create mode 100644 assets/js/21c3df7e.50db2763.js delete mode 100644 assets/js/21c3df7e.d6eeaef8.js rename assets/js/{3021cf83.d7459cdf.js => 3021cf83.3c388bdd.js} (88%) rename assets/js/{3334719e.e92460df.js => 3334719e.ef315589.js} (57%) create mode 100644 assets/js/37e83d0a.b9c42019.js delete mode 100644 assets/js/37e83d0a.df8013bf.js rename assets/js/{393be207.6c4a0910.js => 393be207.579ed0c1.js} (81%) delete mode 100644 assets/js/3e3bd4e4.3abddf15.js create mode 100644 assets/js/3e3bd4e4.c1ead911.js create mode 100644 assets/js/3f288906.aae31196.js delete mode 100644 assets/js/3f288906.c4742133.js delete mode 100644 assets/js/45395bfd.0c0531e4.js create mode 100644 assets/js/45395bfd.e0a879e0.js create mode 100644 assets/js/520.6480633a.js delete mode 100644 assets/js/531df37a.87b69254.js create mode 100644 assets/js/531df37a.d0a2f7b8.js create mode 100644 assets/js/6913d2c8.3d3ea882.js delete mode 100644 assets/js/6913d2c8.ea6cb356.js rename assets/js/{72140a3c.3cf290c5.js => 72140a3c.6899ebb8.js} (78%) rename assets/js/{7281c5db.727eea00.js => 7281c5db.d4799824.js} (57%) delete mode 100644 assets/js/8167aad2.4f6a095b.js create mode 100644 assets/js/8167aad2.cf954963.js delete mode 100644 assets/js/89113871.2ac48097.js create mode 100644 assets/js/89113871.c9befc60.js delete mode 100644 assets/js/935f2afb.21b271de.js create mode 100644 assets/js/935f2afb.b89b4ba2.js create mode 100644 assets/js/9d628f83.1eb64dad.js delete mode 100644 assets/js/9d628f83.894c32a1.js create mode 100644 assets/js/a8b2a833.0897f0d6.js delete mode 100644 assets/js/a8b2a833.a681ab19.js delete mode 100644 assets/js/b27c2848.993481cc.js create mode 100644 assets/js/b27c2848.b50282bd.js delete mode 100644 assets/js/bdef968a.17f76d20.js create mode 100644 assets/js/bdef968a.951df9ba.js delete mode 100644 assets/js/d10e8d20.7fb672e0.js create mode 100644 assets/js/d10e8d20.e9d8a91e.js create mode 100644 assets/js/dde0a8be.8807e4a0.js delete mode 100644 assets/js/dde0a8be.e14f11c5.js create mode 100644 assets/js/eb1ab973.0f5c4678.js delete mode 100644 assets/js/eb1ab973.4ae66d14.js delete mode 100644 assets/js/main.02395a04.js create mode 100644 assets/js/main.205ef86e.js rename assets/js/{main.02395a04.js.LICENSE.txt => main.205ef86e.js.LICENSE.txt} (100%) delete mode 100644 assets/js/runtime~main.0873ad78.js create mode 100644 assets/js/runtime~main.ab27205f.js diff --git a/404.html b/404.html index 0c9c7c4e..a7576827 100644 --- a/404.html +++ b/404.html @@ -3,14 +3,14 @@ -Page Not Found | TypeDI - - +Page Not Found | TypeDI + +
-
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+ + \ No newline at end of file diff --git a/assets/js/0e88606a.5b195619.js b/assets/js/0e88606a.5b195619.js new file mode 100644 index 00000000..2cf4adcc --- /dev/null +++ b/assets/js/0e88606a.5b195619.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[356],{9613:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>y});var r=t(9496);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=r.createContext({}),u=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=u(e.components);return r.createElement(s.Provider,{value:n},e.children)},l="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),l=u(t),d=o,y=l["".concat(s,".").concat(d)]||l[d]||m[d]||a;return t?r.createElement(y,i(i({ref:n},p),{},{components:t})):r.createElement(y,i({ref:n},p))}));function y(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=d;var c={};for(var s in n)hasOwnProperty.call(n,s)&&(c[s]=n[s]);c.originalType=e,c[l]="string"==typeof e?e:o,i[1]=c;for(var u=2;u{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var r=t(1966),o=(t(9496),t(9613));const a={sidebar_position:1},i="Custom Containers",c={unversionedId:"guide/containers/custom-containers",id:"guide/containers/custom-containers",title:"Custom Containers",description:"In some scenarios, you may wish to change how containers work.",source:"@site/docs/guide/containers/custom-containers.md",sourceDirName:"guide/containers",slug:"/guide/containers/custom-containers",permalink:"/docs/guide/containers/custom-containers",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/containers/custom-containers.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Containers",permalink:"/docs/guide/containers/introduction"},next:{title:"Creating Containers",permalink:"/docs/guide/containers/creating-containers"}},s={},u=[],p={toc:u},l="wrapper";function m(e){let{components:n,...t}=e;return(0,o.kt)(l,(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"custom-containers"},"Custom Containers"),(0,o.kt)("p",null,"In some scenarios, you may wish to change how containers work.\nIn this case, ",(0,o.kt)("em",{parentName:"p"},"custom containers")," may be appropriate."),(0,o.kt)("p",null,"In TypeDI, each container is always an instance of ",(0,o.kt)("inlineCode",{parentName:"p"},"ContainerInstance"),".\nHowever, you can ",(0,o.kt)("em",{parentName:"p"},"extend")," this class with custom functionality, and\nthen register it as an ordinary container."),(0,o.kt)("p",null,"In practice, this looks like the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, ContainerRegistry, ServiceIdentifier, ContainerIdentifier } from '@freshgum/typedi';\n\nexport class MyContainerInstance {\n public constructor(id: ContainerIdentifier, parent?: ContainerInstance) {\n super(id, parent);\n }\n\n // ...\n}\n\nconst newContainer = new MyContainerInstance('my-new-container');\nContainerRegistry.registerContainer(newContainer);\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Your custom container class will need a ",(0,o.kt)("inlineCode",{parentName:"p"},"public")," constructor as,\ncurrently, TypeDI's ",(0,o.kt)("inlineCode",{parentName:"p"},"ContainerInstance")," has a ",(0,o.kt)("inlineCode",{parentName:"p"},"protected")," constructor.")),(0,o.kt)("p",null,"Once your custom container has been registered, it functions as an ordinary\ncontainer. Calls to methods such as ",(0,o.kt)("inlineCode",{parentName:"p"},"ContainerInstance.of")," return the custom instance."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0e88606a.c0cb7e70.js b/assets/js/0e88606a.c0cb7e70.js deleted file mode 100644 index f44fc48f..00000000 --- a/assets/js/0e88606a.c0cb7e70.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[356],{9613:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>y});var r=t(9496);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=r.createContext({}),p=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=p(e.components);return r.createElement(s.Provider,{value:n},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),l=p(t),m=o,y=l["".concat(s,".").concat(m)]||l[m]||d[m]||a;return t?r.createElement(y,i(i({ref:n},u),{},{components:t})):r.createElement(y,i({ref:n},u))}));function y(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var c={};for(var s in n)hasOwnProperty.call(n,s)&&(c[s]=n[s]);c.originalType=e,c[l]="string"==typeof e?e:o,i[1]=c;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>p});var r=t(1966),o=(t(9496),t(9613));const a={sidebar_position:1},i="Custom Containers",c={unversionedId:"guide/containers/custom-containers",id:"guide/containers/custom-containers",title:"Custom Containers",description:"In some scenarios, you may wish to change how containers work.",source:"@site/docs/guide/containers/custom-containers.md",sourceDirName:"guide/containers",slug:"/guide/containers/custom-containers",permalink:"/typedi/docs/guide/containers/custom-containers",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/containers/custom-containers.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Containers",permalink:"/typedi/docs/guide/containers/introduction"},next:{title:"Creating Containers",permalink:"/typedi/docs/guide/containers/creating-containers"}},s={},p=[],u={toc:p},l="wrapper";function d(e){let{components:n,...t}=e;return(0,o.kt)(l,(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"custom-containers"},"Custom Containers"),(0,o.kt)("p",null,"In some scenarios, you may wish to change how containers work.\nIn this case, ",(0,o.kt)("em",{parentName:"p"},"custom containers")," may be appropriate."),(0,o.kt)("p",null,"In TypeDI, each container is always an instance of ",(0,o.kt)("inlineCode",{parentName:"p"},"ContainerInstance"),".\nHowever, you can ",(0,o.kt)("em",{parentName:"p"},"extend")," this class with custom functionality, and\nthen register it as an ordinary container."),(0,o.kt)("p",null,"In practice, this looks like the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, ContainerRegistry, ServiceIdentifier, ContainerIdentifier } from '@typed-inject/injector';\n\nexport class MyContainerInstance {\n public constructor(id: ContainerIdentifier, parent?: ContainerInstance) {\n super(id, parent);\n }\n\n // ...\n}\n\nconst newContainer = new MyContainerInstance('my-new-container');\nContainerRegistry.registerContainer(newContainer);\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Your custom container class will need a ",(0,o.kt)("inlineCode",{parentName:"p"},"public")," constructor as,\ncurrently, TypeDI's ",(0,o.kt)("inlineCode",{parentName:"p"},"ContainerInstance")," has a ",(0,o.kt)("inlineCode",{parentName:"p"},"protected")," constructor.")),(0,o.kt)("p",null,"Once your custom container has been registered, it functions as an ordinary\ncontainer. Calls to methods such as ",(0,o.kt)("inlineCode",{parentName:"p"},"ContainerInstance.of")," return the custom instance."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1c20f44b.bb83176f.js b/assets/js/1c20f44b.bb83176f.js new file mode 100644 index 00000000..15be1ada --- /dev/null +++ b/assets/js/1c20f44b.bb83176f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[734],{9613:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var a=t(9496);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=a.createContext({}),s=function(e){var n=a.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},p=function(e){var n=s(e.components);return a.createElement(c.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(t),h=o,f=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return t?a.createElement(f,r(r({ref:n},p),{},{components:t})):a.createElement(f,r({ref:n},p))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,r=new Array(i);r[0]=h;var l={};for(var c in n)hasOwnProperty.call(n,c)&&(l[c]=n[c]);l.originalType=e,l[u]="string"==typeof e?e:o,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var a=t(1966),o=(t(9496),t(9613));const i={sidebar_position:2},r="Creating Containers",l={unversionedId:"guide/containers/creating-containers",id:"guide/containers/creating-containers",title:"Creating Containers",description:"TypeDI maintains a global container registry, which is a shared",source:"@site/docs/guide/containers/creating-containers.md",sourceDirName:"guide/containers",slug:"/guide/containers/creating-containers",permalink:"/docs/guide/containers/creating-containers",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/containers/creating-containers.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Custom Containers",permalink:"/docs/guide/containers/custom-containers"},next:{title:"Services",permalink:"/docs/guide/services/introduction"}},c={},s=[{value:"ContainerInstance.of(id, parent?, options?)",id:"containerinstanceofid-parent-options",level:2},{value:"Container.of(id, options?)",id:"containerofid-options",level:2},{value:"Container.ofChild(id, options?)",id:"containerofchildid-options",level:2},{value:"Creation Options",id:"creation-options",level:2},{value:"Dealing with conflicts",id:"dealing-with-conflicts",level:3},{value:"Real-life example of conflict strategies",id:"real-life-example-of-conflict-strategies",level:3},{value:"Dealing with free IDs",id:"dealing-with-free-ids",level:3},{value:"Defining a conflict",id:"defining-a-conflict",level:3}],p={toc:s},u="wrapper";function d(e){let{components:n,...t}=e;return(0,o.kt)(u,(0,a.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"creating-containers"},"Creating Containers"),(0,o.kt)("p",null,"TypeDI maintains a global container registry, which is a shared\nregistry of all containers it knows about.",(0,o.kt)("br",{parentName:"p"}),"\n","Aside from ",(0,o.kt)("a",{parentName:"p",href:"/docs/guide/containers/custom-containers"},"custom containers"),", all newly-created\ncontainers are added to the registry."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"By default, if a container with the same name already\nexists, it is returned.")),(0,o.kt)("p",null,"There are multiple ways to create a container, each of which\nwill be demonstrated below."),(0,o.kt)("h2",{id:"containerinstanceofid-parent-options"},(0,o.kt)("inlineCode",{parentName:"h2"},"ContainerInstance.of(id, parent?, options?)")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/classes/ContainerInstance.html#of-2"},(0,o.kt)("sup",null,(0,o.kt)("strong",{parentName:"a"},"API Reference")))),(0,o.kt)("p",null,"The static ",(0,o.kt)("inlineCode",{parentName:"p"},"of")," method can be used to create both orphaned and child containers, like so:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, Container } from '@freshgum/typedi';\n\n// Create an orphaned container:\nContainerInstance.of('my-new-container', null);\n\n// Create a container as a child of the default container:\nContainerInstance.of('my-second-new-container', Container);\n")),(0,o.kt)("p",null,"If the second parameter, ",(0,o.kt)("inlineCode",{parentName:"p"},"parent"),", is not provided, then it defaults to the default container."),(0,o.kt)("h2",{id:"containerofid-options"},(0,o.kt)("inlineCode",{parentName:"h2"},"Container.of(id, options?)")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/classes/ContainerInstance.html#of"},(0,o.kt)("sup",null,(0,o.kt)("strong",{parentName:"a"},"API Reference")))),(0,o.kt)("p",null,"The instance method ",(0,o.kt)("inlineCode",{parentName:"p"},"of")," can also be used to create containers,\nin\nXXX"),(0,o.kt)("h2",{id:"containerofchildid-options"},(0,o.kt)("inlineCode",{parentName:"h2"},"Container.ofChild(id, options?)")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/classes/ContainerInstance.html#ofChild"},(0,o.kt)("sup",null,(0,o.kt)("strong",{parentName:"a"},"API Reference")))),(0,o.kt)("p",null,"The instance ",(0,o.kt)("inlineCode",{parentName:"p"},"ofChild")," method can be used to create a container\nwhich is a child of the current. For example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@freshgum/typedi';\n\n// Create a child of the default container:\nconst newContainer = Container.ofChild('my-new-container');\nassert(newContainer.parent === Container);\n\n// You can also create a child of a child!\nconst newNewContainer = newContainer.ofChild('my-really-new-container');\nassert(newNewContainer.parent === newContainer);\n")),(0,o.kt)("h2",{id:"creation-options"},"Creation Options"),(0,o.kt)("p",null,"In each of the above methods, an options parameter ",(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/interfaces/CreateContainerOptions.html"},"of type ",(0,o.kt)("inlineCode",{parentName:"a"},"CreateContainerOptions"))," can optionally be provided.\nThese options dictate how TypeDI should handle certain situations, such as when..."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"a container with the ID already exists ",(0,o.kt)("em",{parentName:"li"},"(a conflict)")),(0,o.kt)("li",{parentName:"ul"},"a container with the ID does not exist ",(0,o.kt)("em",{parentName:"li"},"(free)"))),(0,o.kt)("h3",{id:"dealing-with-conflicts"},"Dealing with conflicts"),(0,o.kt)("p",null,"In many situations, you'll want an operation to fail if it means\nit returns a container with the same ID, but with completely different characteristics."),(0,o.kt)("p",null,"Consider the following ",(0,o.kt)("em",{parentName:"p"},"(incorrect)")," example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Create an orphaned container.\nContainerInstance.of('my-container', null);\n\n// Create a child of the default container.\n// highlight-error-comment-start\nContainer.ofChild('my-container');\n// highlight-error-comment-end\n")),(0,o.kt)("p",null,"As the call to ",(0,o.kt)("inlineCode",{parentName:"p"},"ofChild")," specifies an ID which already exists in the container registry,\nthe existing (orphaned) container is returned. In most cases, this ",(0,o.kt)("em",{parentName:"p"},"isn't")," what you want.\nTo remedy this, we can append a list of options to our ",(0,o.kt)("inlineCode",{parentName:"p"},"ofChild")," call to fail if a\ncontainer with the ID already exists."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Create an orphaned container.\nContainerInstance.of('my-container', null);\n\n// Create a child of the default container.\nContainer.ofChild('my-container', {\n onConflict: 'throw',\n});\n")),(0,o.kt)("p",null,"The above example will throw an error due to the conflicting container IDs.\nThis is one of three ",(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/types/ContainerConflictStrategy.html"},"conflict strategies")," you can choose to resolve a conflict."),(0,o.kt)("p",null,"The others are as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'returnExisting'"),": Return the existing container. This is the default."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'throw'"),": Throw an error upon conflict."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'null'"),": Return null upon conflict.`")),(0,o.kt)("p",null,"A better solution would be to restrict the use of well-known string-based keys, replacing\nthem with well-known instances of ",(0,o.kt)("inlineCode",{parentName:"p"},"Symbol"),". Symbols, even with the same name, will never collide."),(0,o.kt)("p",null,"Let's update our example above to make use of Symbols instead:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export const MY_CONTAINER = Symbol('my-container');\nexport const MY_SECOND_CONTAINER = Symbol('my-container');\n\n// Create an orphaned container.\nContainerInstance.of(MY_CONTAINER, null);\n\n// Create a child of the default container.\nContainerInstance.of(MY_SECOND_CONTAINER);\n")),(0,o.kt)("h3",{id:"real-life-example-of-conflict-strategies"},"Real-life example of conflict strategies"),(0,o.kt)("p",null,"Consider the following example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, Token } from '@freshgum/typedi';\n\n// Keep the container ID local, so other packages have to use\n// our function below to create the container.\nconst VALUE_CONTAINER = Symbol('value');\n\nexport const START_TIME = new Token();\n\nfunction getValueContainer() {\n const container = ContainerInstance.of(VALUE_CONTAINER, null, {\n onConflict: 'null',\n });\n\n // If we've already created the container, the above call returns null.\n if (container) {\n container.setValue(START_TIME, performance.now());\n }\n\n // If we've already set up the container, 'container' will be null.\n // However, we still want to return it here, so we re-get it without a conflict strategy.\n return container ?? ContainerInstance.of(VALUE_CONTAINER);\n}\n\n// ...\n\nfunction logEvents() {\n // Get the time when the application started.\n const startTime = getValueContainer().get(START_TIME);\n // ...\n}\n")),(0,o.kt)("h3",{id:"dealing-with-free-ids"},"Dealing with free IDs"),(0,o.kt)("p",null,"In some cases, you may not want a container to be created if the ID isn't in use."),(0,o.kt)("p",null,"For argument's sake, let's say your application sets up a container with specific values.\nA good way to ensure the container is always instantiated correctly can be found below."),(0,o.kt)("p",null,"Let's tweak our event-logging example above to incorporate the usage of ",(0,o.kt)("em",{parentName:"p"},"free strategies")," instead."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, Token } from '@freshgum/typedi';\n\n// Keep the container ID local, so other packages have to use\n// our function below to create the container.\nconst VALUE_CONTAINER = Symbol('value');\n\nexport const START_TIME = new Token();\n\nfunction getValueContainer() {\n // ...\n}\n\n// ...\n\nfunction logEvents() {\n // Get the value container.\n const valueContainer = ContainerInstance.of(VALUE_CONTAINER, null, {\n onFree: 'null',\n });\n\n if (valueContainer === null) {\n // Oh no! We've forgotten to call `getValueContainer`.\n return;\n }\n\n // Get the time when the application started.\n const startTime = valueContainer.get(START_TIME);\n // ...\n}\n")),(0,o.kt)("h3",{id:"defining-a-conflict"},"Defining a conflict"),(0,o.kt)("p",null,"In some cases, your definition of a conflict may differ from TypeDI's default, which\nchecks whether another container with the same ID already exists."),(0,o.kt)("p",null,"In this case, the library helpfully provides a way to define what a conflict ",(0,o.kt)("em",{parentName:"p"},"is"),".\nThis is done through ",(0,o.kt)("a",{parentName:"p",href:"pathname:/api-reference/types/ContainerConflictDefinition.html"},"conflict definitions"),"."),(0,o.kt)("p",null,"Currently, there are two ways to define a conflict:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'rejectAll'"),": This is the default."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'allowSameParent'"),": Allow conflicts with containers with the same container to the one provided.")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"If you pass a conflict definition without an accompany strategy,\nby default, TypeDI will throw an error if a conflict arises.")),(0,o.kt)("p",null,"In the case of ",(0,o.kt)("inlineCode",{parentName:"p"},"allowSameParent"),", if a conflict were to arise, TypeDI would check whether\nthe parent of the conflicting container matches the one you expected. If not, the strategy is executed."),(0,o.kt)("p",null,"Let's look at an example below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@freshgum/typedi';\n\n// Create a child container of the default container.\nContainer.ofChild('my-new-container');\n\n// Do the same thing again.\nContainer.ofChild('my-new-container', {\n onConflict: 'throw',\n conflictDefinition: 'allowSameParent',\n});\n")),(0,o.kt)("p",null,"In the above example, the second call succeeds, even though the specified ID already exists in the registry.\nWithout the explicit conflict definition, the above call would throw."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1c20f44b.c2dd1418.js b/assets/js/1c20f44b.c2dd1418.js deleted file mode 100644 index 189e7f00..00000000 --- a/assets/js/1c20f44b.c2dd1418.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[734],{9613:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var a=t(9496);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=a.createContext({}),s=function(e){var n=a.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},p=function(e){var n=s(e.components);return a.createElement(c.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},h=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(t),h=o,f=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return t?a.createElement(f,r(r({ref:n},p),{},{components:t})):a.createElement(f,r({ref:n},p))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,r=new Array(i);r[0]=h;var l={};for(var c in n)hasOwnProperty.call(n,c)&&(l[c]=n[c]);l.originalType=e,l[u]="string"==typeof e?e:o,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var a=t(1966),o=(t(9496),t(9613));const i={sidebar_position:2},r="Creating Containers",l={unversionedId:"guide/containers/creating-containers",id:"guide/containers/creating-containers",title:"Creating Containers",description:"TypeDI maintains a global container registry, which is a shared",source:"@site/docs/guide/containers/creating-containers.md",sourceDirName:"guide/containers",slug:"/guide/containers/creating-containers",permalink:"/typedi/docs/guide/containers/creating-containers",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/containers/creating-containers.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Custom Containers",permalink:"/typedi/docs/guide/containers/custom-containers"},next:{title:"Services",permalink:"/typedi/docs/guide/services/introduction"}},c={},s=[{value:"ContainerInstance.of(id, parent?, options?)",id:"containerinstanceofid-parent-options",level:2},{value:"Container.of(id, options?)",id:"containerofid-options",level:2},{value:"Container.ofChild(id, options?)",id:"containerofchildid-options",level:2},{value:"Creation Options",id:"creation-options",level:2},{value:"Dealing with conflicts",id:"dealing-with-conflicts",level:3},{value:"Real-life example of conflict strategies",id:"real-life-example-of-conflict-strategies",level:3},{value:"Dealing with free IDs",id:"dealing-with-free-ids",level:3},{value:"Defining a conflict",id:"defining-a-conflict",level:3}],p={toc:s},u="wrapper";function d(e){let{components:n,...t}=e;return(0,o.kt)(u,(0,a.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"creating-containers"},"Creating Containers"),(0,o.kt)("p",null,"TypeDI maintains a global container registry, which is a shared\nregistry of all containers it knows about.",(0,o.kt)("br",{parentName:"p"}),"\n","Aside from ",(0,o.kt)("a",{parentName:"p",href:"/typedi/docs/guide/containers/custom-containers"},"custom containers"),", all newly-created\ncontainers are added to the registry."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"By default, if a container with the same name already\nexists, it is returned.")),(0,o.kt)("p",null,"There are multiple ways to create a container, each of which\nwill be demonstrated below."),(0,o.kt)("h2",{id:"containerinstanceofid-parent-options"},(0,o.kt)("inlineCode",{parentName:"h2"},"ContainerInstance.of(id, parent?, options?)")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/classes/ContainerInstance.html#of-2"},(0,o.kt)("sup",null,(0,o.kt)("strong",{parentName:"a"},"API Reference")))),(0,o.kt)("p",null,"The static ",(0,o.kt)("inlineCode",{parentName:"p"},"of")," method can be used to create both orphaned and child containers, like so:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, Container } from '@typed-inject/injector';\n\n// Create an orphaned container:\nContainerInstance.of('my-new-container', null);\n\n// Create a container as a child of the default container:\nContainerInstance.of('my-second-new-container', Container);\n")),(0,o.kt)("p",null,"If the second parameter, ",(0,o.kt)("inlineCode",{parentName:"p"},"parent"),", is not provided, then it defaults to the default container."),(0,o.kt)("h2",{id:"containerofid-options"},(0,o.kt)("inlineCode",{parentName:"h2"},"Container.of(id, options?)")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/classes/ContainerInstance.html#of"},(0,o.kt)("sup",null,(0,o.kt)("strong",{parentName:"a"},"API Reference")))),(0,o.kt)("p",null,"The instance method ",(0,o.kt)("inlineCode",{parentName:"p"},"of")," can also be used to create containers,\nin\nXXX"),(0,o.kt)("h2",{id:"containerofchildid-options"},(0,o.kt)("inlineCode",{parentName:"h2"},"Container.ofChild(id, options?)")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/classes/ContainerInstance.html#ofChild"},(0,o.kt)("sup",null,(0,o.kt)("strong",{parentName:"a"},"API Reference")))),(0,o.kt)("p",null,"The instance ",(0,o.kt)("inlineCode",{parentName:"p"},"ofChild")," method can be used to create a container\nwhich is a child of the current. For example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@typed-inject/injector';\n\n// Create a child of the default container:\nconst newContainer = Container.ofChild('my-new-container');\nassert(newContainer.parent === Container);\n\n// You can also create a child of a child!\nconst newNewContainer = newContainer.ofChild('my-really-new-container');\nassert(newNewContainer.parent === newContainer);\n")),(0,o.kt)("h2",{id:"creation-options"},"Creation Options"),(0,o.kt)("p",null,"In each of the above methods, an options parameter ",(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/interfaces/CreateContainerOptions.html"},"of type ",(0,o.kt)("inlineCode",{parentName:"a"},"CreateContainerOptions"))," can optionally be provided.\nThese options dictate how TypeDI should handle certain situations, such as when..."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"a container with the ID already exists ",(0,o.kt)("em",{parentName:"li"},"(a conflict)")),(0,o.kt)("li",{parentName:"ul"},"a container with the ID does not exist ",(0,o.kt)("em",{parentName:"li"},"(free)"))),(0,o.kt)("h3",{id:"dealing-with-conflicts"},"Dealing with conflicts"),(0,o.kt)("p",null,"In many situations, you'll want an operation to fail if it means\nit returns a container with the same ID, but with completely different characteristics."),(0,o.kt)("p",null,"Consider the following ",(0,o.kt)("em",{parentName:"p"},"(incorrect)")," example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Create an orphaned container.\nContainerInstance.of('my-container', null);\n\n// Create a child of the default container.\n// highlight-error-comment-start\nContainer.ofChild('my-container');\n// highlight-error-comment-end\n")),(0,o.kt)("p",null,"As the call to ",(0,o.kt)("inlineCode",{parentName:"p"},"ofChild")," specifies an ID which already exists in the container registry,\nthe existing (orphaned) container is returned. In most cases, this ",(0,o.kt)("em",{parentName:"p"},"isn't")," what you want.\nTo remedy this, we can append a list of options to our ",(0,o.kt)("inlineCode",{parentName:"p"},"ofChild")," call to fail if a\ncontainer with the ID already exists."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Create an orphaned container.\nContainerInstance.of('my-container', null);\n\n// Create a child of the default container.\nContainer.ofChild('my-container', {\n onConflict: 'throw',\n});\n")),(0,o.kt)("p",null,"The above example will throw an error due to the conflicting container IDs.\nThis is one of three ",(0,o.kt)("a",{parentName:"p",href:"pathname:///api-reference/types/ContainerConflictStrategy.html"},"conflict strategies")," you can choose to resolve a conflict."),(0,o.kt)("p",null,"The others are as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'returnExisting'"),": Return the existing container. This is the default."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'throw'"),": Throw an error upon conflict."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'null'"),": Return null upon conflict.`")),(0,o.kt)("p",null,"A better solution would be to restrict the use of well-known string-based keys, replacing\nthem with well-known instances of ",(0,o.kt)("inlineCode",{parentName:"p"},"Symbol"),". Symbols, even with the same name, will never collide."),(0,o.kt)("p",null,"Let's update our example above to make use of Symbols instead:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export const MY_CONTAINER = Symbol('my-container');\nexport const MY_SECOND_CONTAINER = Symbol('my-container');\n\n// Create an orphaned container.\nContainerInstance.of(MY_CONTAINER, null);\n\n// Create a child of the default container.\nContainerInstance.of(MY_SECOND_CONTAINER);\n")),(0,o.kt)("h3",{id:"real-life-example-of-conflict-strategies"},"Real-life example of conflict strategies"),(0,o.kt)("p",null,"Consider the following example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, Token } from '@typed-inject/injector';\n\n// Keep the container ID local, so other packages have to use\n// our function below to create the container.\nconst VALUE_CONTAINER = Symbol('value');\n\nexport const START_TIME = new Token();\n\nfunction getValueContainer() {\n const container = ContainerInstance.of(VALUE_CONTAINER, null, {\n onConflict: 'null',\n });\n\n // If we've already created the container, the above call returns null.\n if (container) {\n container.setValue(START_TIME, performance.now());\n }\n\n // If we've already set up the container, 'container' will be null.\n // However, we still want to return it here, so we re-get it without a conflict strategy.\n return container ?? ContainerInstance.of(VALUE_CONTAINER);\n}\n\n// ...\n\nfunction logEvents() {\n // Get the time when the application started.\n const startTime = getValueContainer().get(START_TIME);\n // ...\n}\n")),(0,o.kt)("h3",{id:"dealing-with-free-ids"},"Dealing with free IDs"),(0,o.kt)("p",null,"In some cases, you may not want a container to be created if the ID isn't in use."),(0,o.kt)("p",null,"For argument's sake, let's say your application sets up a container with specific values.\nA good way to ensure the container is always instantiated correctly can be found below."),(0,o.kt)("p",null,"Let's tweak our event-logging example above to incorporate the usage of ",(0,o.kt)("em",{parentName:"p"},"free strategies")," instead."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, Token } from '@typed-inject/injector';\n\n// Keep the container ID local, so other packages have to use\n// our function below to create the container.\nconst VALUE_CONTAINER = Symbol('value');\n\nexport const START_TIME = new Token();\n\nfunction getValueContainer() {\n // ...\n}\n\n// ...\n\nfunction logEvents() {\n // Get the value container.\n const valueContainer = ContainerInstance.of(VALUE_CONTAINER, null, {\n onFree: 'null',\n });\n\n if (valueContainer === null) {\n // Oh no! We've forgotten to call `getValueContainer`.\n return;\n }\n\n // Get the time when the application started.\n const startTime = valueContainer.get(START_TIME);\n // ...\n}\n")),(0,o.kt)("h3",{id:"defining-a-conflict"},"Defining a conflict"),(0,o.kt)("p",null,"In some cases, your definition of a conflict may differ from TypeDI's default, which\nchecks whether another container with the same ID already exists."),(0,o.kt)("p",null,"In this case, the library helpfully provides a way to define what a conflict ",(0,o.kt)("em",{parentName:"p"},"is"),".\nThis is done through ",(0,o.kt)("a",{parentName:"p",href:"pathname:/api-reference/types/ContainerConflictDefinition.html"},"conflict definitions"),"."),(0,o.kt)("p",null,"Currently, there are two ways to define a conflict:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'rejectAll'"),": This is the default."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"'allowSameParent'"),": Allow conflicts with containers with the same container to the one provided.")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"If you pass a conflict definition without an accompany strategy,\nby default, TypeDI will throw an error if a conflict arises.")),(0,o.kt)("p",null,"In the case of ",(0,o.kt)("inlineCode",{parentName:"p"},"allowSameParent"),", if a conflict were to arise, TypeDI would check whether\nthe parent of the conflicting container matches the one you expected. If not, the strategy is executed."),(0,o.kt)("p",null,"Let's look at an example below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@typed-inject/injector';\n\n// Create a child container of the default container.\nContainer.ofChild('my-new-container');\n\n// Do the same thing again.\nContainer.ofChild('my-new-container', {\n onConflict: 'throw',\n conflictDefinition: 'allowSameParent',\n});\n")),(0,o.kt)("p",null,"In the above example, the second call succeeds, even though the specified ID already exists in the registry.\nWithout the explicit conflict definition, the above call would throw."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.0e81d588.js b/assets/js/1df93b7f.0e81d588.js deleted file mode 100644 index 074c82f0..00000000 --- a/assets/js/1df93b7f.0e81d588.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[237],{1019:(e,t,a)=>{a.d(t,{b:()=>s});var n=a(9751);function s(){return(0,n.Z)(...arguments)}},1089:(e,t,a)=>{a.r(t),a.d(t,{default:()=>R});var n=a(9496),s=a(5924),r=a(5347),o=a(5985);const l={heroBanner:"heroBanner_qdFl",hero__title:"hero__title_sobY",buttons:"buttons_AeoN"};var c=a(1019),m=a(5474),i=a(8450);const u={featureList:"featureList_rzYb",featureListItem:"featureListItem_sqlS",sideBySide:"sideBySide_BTmA",displayInline:"displayInline_uutu",demoCodeBlock:"demoCodeBlock_UWHu",featureListItemLeadup:"featureListItemLeadup_fJxF",leadupHeading:"leadupHeading_V3Dv",leadupSummary:"leadupSummary__Ds9",featureListItemDemo:"featureListItemDemo_sN7h"};var d=a(9893);const p=new d.W("All posts for logged-in users.");var f=a(7877);function h(e,t){void 0===t&&(t=f.W2);return[(0,n.useMemo)((()=>t.getOrNull(e)),[e])]}const E={fakeFeedContent:"fakeFeedContent_Bnwo",fakeChatList:"fakeChatList_wPuv",roundedHeavy:"roundedHeavy_AAAn",contentGrow:"contentGrow_B723",fakeFeedBottomRack:"fakeFeedBottomRack_pwBD"},g={messageAuthor:"messageAuthor_YNfL",messageContent:"messageContent_reyZ",fakePost:"fakePost_WaTo"};function v(e){let{post:t,key:a,isListItem:s=!1}=e;return n.createElement("div",{className:g.fakePost,key:a,role:"listitem","aria-label":"Example of a post made using the FeedService"},n.createElement("p",{className:g.messageContent},n.createElement("span",{className:g.messageAuthor},t.username),n.createElement("span",{className:g.messageContent},t.post)))}const N={bottomRack:"bottomRack_Vziq",messageForm:"messageForm_eYqj",messageInput:"messageInput_AdId",submitButton:"submitButton_jx_S"};function _(e){const t=(0,n.useRef)();return n.createElement("div",{className:N.bottomRack},n.createElement("form",{className:N.messageForm,onSubmit:a=>{const n=t.current;a.preventDefault(),a.stopPropagation(),e.onNewMessage?.(n.value,a),n.value=""}},n.createElement("input",{type:"text",className:N.messageInput,placeholder:"Enter a message...",ref:t})))}var b=a(8772);const k=new d.W("The username of the current user.");let y=0;class w extends EventTarget{constructor(e,t){super(),this.username=e,this.posts=t}addPost(e){this.posts.push({username:this.username,post:e,id:++y}),this.dispatchEvent(new CustomEvent("post-added"))}}function Z(){const[e]=function(){const[,e]=(0,n.useState)(null);return[function(){e({})}]}(),[t]=h(w),[a]=h(p),r=(0,n.useRef)(),o=(0,n.useRef)(!1);return(0,n.useEffect)((()=>{t.addEventListener("post-added",(()=>{e(),o.current=!0}))}),[]),(0,n.useLayoutEffect)((()=>{o.current&&(o.current=!1,r.current.scrollTop=r.current.scrollHeight)})),n.createElement("div",{className:E.fakeFeed,"aria-label":"An interactive example of a FeedService"},n.createElement("div",{className:(0,s.Z)(E.fakeFeedContent,"shadow--tl")},n.createElement("div",{className:(0,s.Z)(E.roundedHeavy,E.contentGrow)},n.createElement("div",{className:E.fakeChatList,ref:r,role:"list","aria-label":"A list of posts as part of the example"},a.map((e=>n.createElement(v,{post:e,key:e.id}))))),n.createElement(_,{onNewMessage:function(e){t.addPost(e)}})))}(0,b.t)([k,p])(w),f.ZP.has(p)||f.ZP.set({id:p,value:[{username:"freshgum",post:"hello! :-)"},{username:"freshgum",post:"try typing here!"}],dependencies:[]}),f.ZP.has(k)||f.ZP.set({id:k,value:"you",dependencies:[]});const S=new d.W("The username of the current user."),I={greetingDemo:"greetingDemo_l0dO",nameInput:"nameInput_ZaNZ"};var L=a(9435);class C{constructor(e){this.userName=e}getGreeting(){return`Hello, ${this.userName??"person"}!`}}function B(){const[e,t]=(0,n.useState)(),a=(0,n.useMemo)((()=>(""===e?f.ZP.remove(S):f.ZP.set({id:S,value:e,dependencies:[]}),f.ZP.get(C))),[e]),r=(0,n.useRef)();return n.createElement("div",{className:(0,s.Z)(I.greetingDemo,"shadow--tl")},n.createElement("div",{className:(0,s.Z)(I.serviceOutput,I.layoutPartition)},n.createElement("p",{className:I.serviceOutputText},a.getGreeting())),n.createElement("form",{className:(0,s.Z)(I.usernameForm,I.layoutPartition)},n.createElement("input",{type:"text",placeholder:"What's your name?",className:I.nameInput,ref:r,onInput:()=>t(r.current.value)})))}(0,b.t)({scope:"transient"},[[S,(0,L.Fi)()]])(C);const P="@Service([USERNAME, POSTS])\nexport class FeedService extends EventTarget {\n constructor (private username: string, private posts: Post[]) {\n super();\n }\n\n addPost (post: string) {\n this.posts.push({ username: this.username, post });\n this.dispatchEvent(new CustomEvent('post-added'));\n }\n}",x="const USERNAME = new Token();\n\n@Service({ scope: 'transient' }, [\n [USERNAME, Optional()]\n])\nexport class GreetingService {\n constructor (private userName?: string) { }\n\n getGreeting () {\n return `Hello, ${this.userName ?? 'person'}!`;\n }\n}\n";function A(){return n.createElement(n.Fragment,null,n.createElement("div",{className:u.featureList},n.createElement("div",{className:(0,s.Z)(u.featureListItem,u.featureListItemDemo)},n.createElement("div",{className:u.featureListItemLeadup},n.createElement("h2",{className:u.leadupHeading},"Injection without the confusion."),n.createElement("p",{className:u.leadupSummary},"All through an expressive, decorator-based syntax.")),n.createElement("div",{className:u.sideBySide},n.createElement("div",{className:u.explainedCodeBlock},n.createElement(m.Z,{language:"ts",className:(0,s.Z)(u.demoCodeBlock,"shadow--tl")},P),n.createElement(i.Z,{summary:"Wondering how this example works?"},"This example uses a combination of the above code and React.",n.createElement("br",null),"The implementation of this example ",n.createElement("a",{href:"https://a.co"},"can be seen here."))),n.createElement(Z,null)),n.createElement("div",{className:(0,s.Z)(u.featureListItemLeadup,"margin-top--lg")},n.createElement("h2",{className:u.leadupHeading},"Angular-esque API"),n.createElement("p",{className:u.leadupSummary},n.createElement("p",null,"TypeDI lets you use operators such as ",n.createElement("code",null,"SkipSelf"),", ",n.createElement("code",null,"Self"),", ",n.createElement("br",null),"and ",n.createElement("code",null,"Optional")," to change how dependencies are retrieved."))),n.createElement("div",{className:u.sideBySide},n.createElement("div",{className:u.explainedCodeBlock},n.createElement(m.Z,{language:"ts",className:(0,s.Z)(u.demoCodeBlock,"shadow--tl")},x)),n.createElement(B,null)))))}function F(){const{siteConfig:e}=(0,c.b)();return n.createElement("header",{className:(0,s.Z)("hero shadow--lw",l.heroBanner)},n.createElement("div",{className:"container"},n.createElement("h1",{className:l.hero__title},e.title),n.createElement("p",{className:"hero__subtitle"},e.tagline),n.createElement("div",{className:l.buttons},n.createElement(r.Z,{className:"button button--primary button--lg",to:"/docs/getting-started"},"Getting Started"),n.createElement(r.Z,{className:"button button--secondary button--lg",to:e.customFields.apiReference.link},"API Reference"))))}function R(){const{siteConfig:e}=(0,c.b)();return n.createElement(o.Z,{title:`Hello from ${e.title}`,description:"Description will go into a meta tag in "},n.createElement(F,null),n.createElement("main",null,n.createElement(A,null)))}},5474:(e,t,a)=>{a.d(t,{Z:()=>r});var n=a(9496),s=a(8517);function r(e){const{title:t}=e;if(t?.startsWith('"')&&!t?.endsWith('"'))throw new Error(`Unterminated quote detected in code-block: ${t}.`);return n.createElement(n.Fragment,null,n.createElement(s.Z,e))}}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.5cf77e22.js b/assets/js/1df93b7f.5cf77e22.js new file mode 100644 index 00000000..20c3f7c8 --- /dev/null +++ b/assets/js/1df93b7f.5cf77e22.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[237],{1019:(e,t,a)=>{a.d(t,{b:()=>s});var n=a(9751);function s(){return(0,n.Z)(...arguments)}},1089:(e,t,a)=>{a.r(t),a.d(t,{default:()=>P});var n=a(9496),s=a(5924),r=a(5347),o=a(5985);const l={heroBanner:"heroBanner_qdFl",hero__title:"hero__title_sobY",buttons:"buttons_AeoN"};var c=a(1019),m=a(5474),i=a(8450);const u={featureList:"featureList_rzYb",featureListItem:"featureListItem_sqlS",sideBySide:"sideBySide_BTmA",displayInline:"displayInline_uutu",demoCodeBlock:"demoCodeBlock_UWHu",featureListItemLeadup:"featureListItemLeadup_fJxF",leadupHeading:"leadupHeading_V3Dv",leadupSummary:"leadupSummary__Ds9",featureListItemDemo:"featureListItemDemo_sN7h"};var d=a(5146);const p=new d.W("All posts for logged-in users.");var f=a(1944);function h(e,t){void 0===t&&(t=f.J);return[(0,n.useMemo)((()=>t.getOrNull(e)),[e])]}const E={fakeFeedContent:"fakeFeedContent_Bnwo",fakeChatList:"fakeChatList_wPuv",roundedHeavy:"roundedHeavy_AAAn",contentGrow:"contentGrow_B723",fakeFeedBottomRack:"fakeFeedBottomRack_pwBD"},g={messageAuthor:"messageAuthor_YNfL",messageContent:"messageContent_reyZ",fakePost:"fakePost_WaTo"};function v(e){let{post:t,key:a,isListItem:s=!1}=e;return n.createElement("div",{className:g.fakePost,key:a,role:"listitem","aria-label":"Example of a post made using the FeedService"},n.createElement("p",{className:g.messageContent},n.createElement("span",{className:g.messageAuthor},t.username),n.createElement("span",{className:g.messageContent},t.post)))}const N={bottomRack:"bottomRack_Vziq",messageForm:"messageForm_eYqj",messageInput:"messageInput_AdId",submitButton:"submitButton_jx_S"};function _(e){const t=(0,n.useRef)();return n.createElement("div",{className:N.bottomRack},n.createElement("form",{className:N.messageForm,onSubmit:a=>{const n=t.current;a.preventDefault(),a.stopPropagation(),e.onNewMessage?.(n.value,a),n.value=""}},n.createElement("input",{type:"text",className:N.messageInput,placeholder:"Enter a message...",ref:t})))}var b=a(1238);const k=new d.W("The username of the current user.");let y=0;class w extends EventTarget{constructor(e,t){super(),this.username=e,this.posts=t}addPost(e){this.posts.push({username:this.username,post:e,id:++y}),this.dispatchEvent(new CustomEvent("post-added"))}}function S(){const[e]=function(){const[,e]=(0,n.useState)(null);return[function(){e({})}]}(),[t]=h(w),[a]=h(p),r=(0,n.useRef)(),o=(0,n.useRef)(!1);return(0,n.useEffect)((()=>{t.addEventListener("post-added",(()=>{e(),o.current=!0}))}),[]),(0,n.useLayoutEffect)((()=>{o.current&&(o.current=!1,r.current.scrollTop=r.current.scrollHeight)})),n.createElement("div",{className:E.fakeFeed,"aria-label":"An interactive example of a FeedService"},n.createElement("div",{className:(0,s.Z)(E.fakeFeedContent,"shadow--tl")},n.createElement("div",{className:(0,s.Z)(E.roundedHeavy,E.contentGrow)},n.createElement("div",{className:E.fakeChatList,ref:r,role:"list","aria-label":"A list of posts as part of the example"},a.map((e=>n.createElement(v,{post:e,key:e.id}))))),n.createElement(_,{onNewMessage:function(e){t.addPost(e)}})))}(0,b.t)([k,p])(w),f.J.has(p)||f.J.set({id:p,value:[{username:"freshgum",post:"hello! :-)"},{username:"freshgum",post:"try typing here!"}],dependencies:[]}),f.J.has(k)||f.J.set({id:k,value:"you",dependencies:[]});const I=new d.W("The username of the current user."),L={greetingDemo:"greetingDemo_l0dO",nameInput:"nameInput_ZaNZ"};var C=a(7010);class Z{constructor(e){this.userName=e}getGreeting(){return`Hello, ${this.userName??"person"}!`}}function B(){const[e,t]=(0,n.useState)(),a=(0,n.useMemo)((()=>(""===e?f.J.remove(I):f.J.set({id:I,value:e,dependencies:[]}),f.J.get(Z))),[e]),r=(0,n.useRef)();return n.createElement("div",{className:(0,s.Z)(L.greetingDemo,"shadow--tl")},n.createElement("div",{className:(0,s.Z)(L.serviceOutput,L.layoutPartition)},n.createElement("p",{className:L.serviceOutputText},a.getGreeting())),n.createElement("form",{className:(0,s.Z)(L.usernameForm,L.layoutPartition)},n.createElement("input",{type:"text",placeholder:"What's your name?",className:L.nameInput,ref:r,onInput:()=>t(r.current.value)})))}(0,b.t)({scope:"transient"},[[I,(0,C.Fi)()]])(Z);const x="@Service([USERNAME, POSTS])\nexport class FeedService extends EventTarget {\n constructor (private username: string, private posts: Post[]) {\n super();\n }\n\n addPost (post: string) {\n this.posts.push({ username: this.username, post });\n this.dispatchEvent(new CustomEvent('post-added'));\n }\n}",A="const USERNAME = new Token();\n\n@Service({ scope: 'transient' }, [\n [USERNAME, Optional()]\n])\nexport class GreetingService {\n constructor (private userName?: string) { }\n\n getGreeting () {\n return `Hello, ${this.userName ?? 'person'}!`;\n }\n}\n";function F(){return n.createElement(n.Fragment,null,n.createElement("div",{className:u.featureList},n.createElement("div",{className:(0,s.Z)(u.featureListItem,u.featureListItemDemo)},n.createElement("div",{className:u.featureListItemLeadup},n.createElement("h2",{className:u.leadupHeading},"Injection without the confusion."),n.createElement("p",{className:u.leadupSummary},"All through an expressive, decorator-based syntax.")),n.createElement("div",{className:u.sideBySide},n.createElement("div",{className:u.explainedCodeBlock},n.createElement(m.Z,{language:"ts",className:(0,s.Z)(u.demoCodeBlock,"shadow--tl")},x),n.createElement(i.Z,{summary:"Wondering how this example works?"},"This example uses a combination of the above code and React.",n.createElement("br",null),"The implementation of this example ",n.createElement("a",{href:"https://a.co"},"can be seen here."))),n.createElement(S,null)),n.createElement("div",{className:(0,s.Z)(u.featureListItemLeadup,"margin-top--lg")},n.createElement("h2",{className:u.leadupHeading},"Angular-esque API"),n.createElement("p",{className:u.leadupSummary},n.createElement("p",null,"TypeDI lets you use operators such as ",n.createElement("code",null,"SkipSelf"),", ",n.createElement("code",null,"Self"),", ",n.createElement("br",null),"and ",n.createElement("code",null,"Optional")," to change how dependencies are retrieved."))),n.createElement("div",{className:u.sideBySide},n.createElement("div",{className:u.explainedCodeBlock},n.createElement(m.Z,{language:"ts",className:(0,s.Z)(u.demoCodeBlock,"shadow--tl")},A)),n.createElement(B,null)))))}function R(){const{siteConfig:e}=(0,c.b)();return n.createElement("header",{className:(0,s.Z)("hero shadow--lw",l.heroBanner)},n.createElement("div",{className:"container"},n.createElement("h1",{className:l.hero__title},e.title),n.createElement("p",{className:"hero__subtitle"},e.tagline),n.createElement("div",{className:l.buttons},n.createElement(r.Z,{className:"button button--primary button--lg",to:"/docs/getting-started"},"Getting Started"),n.createElement(r.Z,{className:"button button--secondary button--lg",to:e.customFields.apiReference.link},"API Reference"))))}function P(){const{siteConfig:e}=(0,c.b)();return n.createElement(o.Z,{title:`Hello from ${e.title}`,description:"Description will go into a meta tag in "},n.createElement(R,null),n.createElement("main",null,n.createElement(F,null)))}},5474:(e,t,a)=>{a.d(t,{Z:()=>r});var n=a(9496),s=a(8517);function r(e){const{title:t}=e;if(t?.startsWith('"')&&!t?.endsWith('"'))throw new Error(`Unterminated quote detected in code-block: ${t}.`);return n.createElement(n.Fragment,null,n.createElement(s.Z,e))}}}]); \ No newline at end of file diff --git a/assets/js/21.9ddbf3f4.js b/assets/js/21.9ddbf3f4.js deleted file mode 100644 index ca5e1d16..00000000 --- a/assets/js/21.9ddbf3f4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[21],{1065:(e,t,r)=>{r.d(t,{z:()=>n});const n=[String,Object,Symbol,Array,Number]},2466:(e,t,r)=>{r.d(t,{I:()=>n});const n=Symbol("EMPTY_VALUE")},3471:(e,t,r)=>{r.d(t,{G:()=>n});const n={multiple:!1,eager:!1,scope:"container",value:r(2466).I,factory:void 0}},2303:(e,t,r)=>{r.d(t,{L:()=>m});class n{static registerContainer(e){if(e instanceof m==!1)throw new Error("Only ContainerInstance instances can be registered.");if(n.containerMap.has(e.id))throw new Error("Cannot register container with same ID.");n.containerMap.set(e.id,e)}static hasContainer(e){return n.containerMap.has(e)}static getContainer(e){const t=this.containerMap.get(e);if(void 0===t)throw new Error("No container is registered with the given ID.");return t}static async removeContainer(e){const t=n.containerMap.get(e.id);if(void 0===t)throw new Error("No container is registered with the given ID.");n.containerMap.delete(e.id),await t.dispose()}}n.containerMap=new Map;var i=r(9893);class a extends Error{get message(){return`Service with "${this.normalizedIdentifier}" identifier was not found in the container. Register it before usage via explicitly calling the "Container.set" function or using the "@Service()" decorator.`}constructor(e){super(),this.name="ServiceNotFoundError",this.normalizedIdentifier="","string"==typeof e?this.normalizedIdentifier=e:e instanceof i.W?this.normalizedIdentifier=`Token<${e.name||"UNSET_NAME"}>`:e&&(e.name||e.prototype?.name)&&(this.normalizedIdentifier=`MaybeConstructable<${e.name}>`||`MaybeConstructable<${e.prototype?.name}>`)}}var s=r(1854),o=r(2466),l=r(1065),c=r(276),d=r(3471),u=r(3809);const p=new i.W("Host Container"),h="throwIfDisposed",f=[p];class m{constructor(e,t){this.parent=t,this.metadataMap=new Map,this.multiServiceIds=new Map,this.disposed=!1,this.id=e}has(e,t=!0){if(this[h](),f.includes(e))return!0;const r=this.getIdentifierLocation(e);return!(!t||"parent"!==r)||"local"===r}getIdentifierLocation(e){return this[h](),this.metadataMap.has(e)||this.multiServiceIds.has(e)?"local":this.parent&&this.parent.has(e,!0)?"parent":"none"}get(e,t){const r=this.getOrNull(e,t);if(null===r)throw new a(e);return r}resolveMetadata(e,t){this[h]();const r=this.getIdentifierLocation(e);switch(r){case"none":return null;case"local":return[this.metadataMap.get(e),r];case"parent":if(t){const t=this.parent?.resolveMetadata(e,!0);return t?[t[0],"parent"]:null}return null}}getOrNull(e,t=!0){if(this[h](),e===p)return this;const r=this.resolveMetadata(e,t);if(null===r)return null;const[n,i]=r;if("parent"===i){const r="singleton"===n.scope?n.value:o.I,i={...n,value:r};if("singleton"===i.scope)return m.defaultContainer.getOrNull(e,t);const a=this.set(i,[...n.dependencies]);return this.getOrNull(a,t)}let a=n;if("singleton"===n?.scope&&(a=m.defaultContainer.metadataMap.get(e)),a&&!0===a.multiple)throw new Error(`Cannot resolve multiple values for ${e.toString()} service!`);return a?this.getServiceValue(a):null}getMany(e,t){const r=this.getManyOrNull(e,t);if(null===r)throw new a(e);return r}getManyOrNull(e,t=!0){let r;if(this[h](),this.multiServiceIds.has(e)?r=this.multiServiceIds.get(e):t&&this.parent&&this.parent.multiServiceIds.has(e)&&(r=this.parent.multiServiceIds.get(e)),!r)return null;const n="singleton"===r.scope?e=>m.defaultContainer.get(e):e=>this.get(e,t);return r.tokens.map(n)}set(e,t){if(this.throwIfDisposed(),"singleton"===e.scope&&m.defaultContainer!==this)return m.defaultContainer.set(e,t);const r=t??e?.dependencies?.map(u.B)??[],n={id:e.id??e.type,type:null,...d.G,...e,dependencies:r};if(n.multiple){const e=new i.W(`MultiMaskToken-${n.id.toString()}`),t=this.multiServiceIds.get(n.id);t?t.tokens.push(e):this.multiServiceIds.set(n.id,{scope:n.scope,tokens:[e]}),n.id=e,n.multiple=!1}return this.metadataMap.set(n.id,n),n.eager&&"transient"!==n.scope&&this.get(n.id),n.id}remove(e){if(this[h](),Array.isArray(e))e.forEach((e=>this.remove(e)));else{const t=this.metadataMap.get(e);t&&(this.disposeServiceInstance(t),this.metadataMap.delete(e))}return this}static of(e="default",t=m.defaultContainer){if("default"===e)return this.defaultContainer;let r;return n.hasContainer(e)?r=n.getContainer(e):(r=new m(e,t??void 0),n.registerContainer(r)),r}of(e){return m.of(e)}ofChild(e){return this[h](),m.of(e,this)}reset(e={strategy:"resetValue"}){switch(this[h](),e.strategy){case"resetValue":this.metadataMap.forEach((e=>this.disposeServiceInstance(e)));break;case"resetServices":this.metadataMap.forEach((e=>this.disposeServiceInstance(e))),this.metadataMap.clear(),this.multiServiceIds.clear();break;default:throw new Error("Received invalid reset strategy.")}return this}async dispose(){this[h](),this.reset({strategy:"resetServices"}),this.disposed=!0}throwIfDisposed(){if(this.disposed)throw new Error("Cannot use container after it has been disposed.")}getServiceValue(e){let t=o.I;const{factory:r}=e;if(e.value!==o.I)return e.value;if(!r&&!e.type)throw new s.Z(e.id);if(r)if(Array.isArray(r)){const[n,i]=r;t=(this.getOrNull(n)??new n)[i](this,e.id)}else t=r(this,e.id);if(!r&&e.type){t=new(0,e.type)(...this.getConstructorParameters(e,!0))}if("transient"!==e.scope&&t!==o.I&&(e.value=t),t===o.I)throw new s.Z(e.id);return t}getConstructorParameters({dependencies:e},t){return 0===e.length?[]:e.map((e=>this.resolveResolvable(e)))}resolveResolvable(e){const t=this.resolveTypeWrapper(e.typeWrapper);if(e.constraints){const{constraints:r}=e;let n;const i=!!(2&r),s=!!(4&r),o=!!(8&r),l=!!(1&r);if(s&&o)throw new Error("SkipSelf() and Self() cannot be used at the same time.");if(s&&!this.parent)throw new Error("The SkipSelf() flag was enabled, but the subject container does not have a parent.");const c=s?this.parent:this,d=!o??void 0;if(!c.has(t,d)){if(i)return null;throw new a(t)}return n=l?c.getMany(t,d):c.get(t,d),n}return this.get(t)}resolveTypeWrapper(e,t=!1){const r=e.eagerType??e.lazyType?.();if(null==r)throw new Error("The wrapped value could not be resolved.");if(t&&l.z.includes(r))throw new c.m(r?.name??r);return r}disposeServiceInstance(e,t=!1){this[h]();if(t||!!e.type||!!e.factory){if("function"==typeof(e?.value).dispose)try{e.value.dispose()}catch(r){}e.value=o.I}}[Symbol.iterator](){return this.metadataMap.entries()}}m.defaultContainer=new m("default"),n.registerContainer(m.defaultContainer)},8772:(e,t,r)=>{r.d(t,{t:()=>c});var n=r(2303);function i(e){return String(e.name||e)}var a=r(3471),s=r(1065),o=r(276),l=r(3809);function c(e,t){return r=>{if(null==e)throw new Error("The required configuration was not passed.");let c;if(Array.isArray(e)?c=e:Array.isArray(t)?c=t:"dependencies"in e&&(c=e.dependencies),!c)throw new Error("The dependencies provided were not able to be resolved.");const d=c.map(l.B);let u={id:r,type:r,...a.G,container:n.L.defaultContainer};Array.isArray(e)||(u={...u,...e},delete u.dependencies);const{id:p,container:h}=u;if(h.has(p)&&h.get(p)===r)throw new Error(`@Service() has been called twice upon ${i(r)}, or you have used an ID twice.`);d.forEach((({typeWrapper:e},t)=>{const{eagerType:n}=e;if(null!==n){const a=typeof e;if("function"!==a&&"object"!==a&&"string"!==a)throw new Error(`The identifier provided at index ${t} for service ${i(r)} is invalid.`);if(null==u.factory&&s.z.includes(n))throw new o.m(n?.name??n)}})),h.set(u,d)}}},276:(e,t,r)=>{r.d(t,{m:()=>i});var n=r(1854);class i extends n.Z{get message(){return super.message+" If your service requires built-in or unresolvable types, please use a factory."}}},1854:(e,t,r)=>{r.d(t,{Z:()=>i});var n=r(9893);class i extends Error{get message(){return`Cannot instantiate the requested value for the "${this.normalizedIdentifier}" identifier. The related metadata doesn't contain a factory or a type to instantiate.`}constructor(e){super(),this.name="CannotInstantiateValueError",this.normalizedIdentifier="","string"==typeof e?this.normalizedIdentifier=e:e instanceof n.W?this.normalizedIdentifier=`Token<${e.name||"UNSET_NAME"}>`:e&&(e.name||e.prototype?.name)&&(this.normalizedIdentifier=`MaybeConstructable<${e.name}>`||`MaybeConstructable<${e.prototype?.name}>`)}}},9435:(e,t,r)=>{function n(){return 2}r.d(t,{Fi:()=>n})},7877:(e,t,r)=>{r.d(t,{W2:()=>n,ZP:()=>i});const n=r(2303).L.defaultContainer,i=n},9893:(e,t,r)=>{r.d(t,{W:()=>n});class n{constructor(e){this.name=e}}},3809:(e,t,r)=>{r.d(t,{B:()=>o});var n=r(9893);const i=Symbol("LAZY_REFERENCE"),a=Symbol("INJECTED_FACTORY");function s(e){let t;return e&&("string"==typeof e||e instanceof n.W||"function"==typeof e)?t={eagerType:e,lazyType:()=>e,isFactory:!1}:"object"==typeof e&&!0===e[a]?t={eagerType:null,factory:e,isFactory:!0}:e&&function(e){return!0===e[i]}(e)&&(t={eagerType:null,lazyType:()=>e.get(),isFactory:!1}),t}function o(e){let t,r;if(Array.isArray(e)){const[n,i]=e;if(null==n||null==i)throw new Error("The dependency pair was not instantiated correctly.");"number"==typeof i&&(t=i),r=s(n)}else r=s(e);return{constraints:t,typeWrapper:r}}},8450:(e,t,r)=>{r.d(t,{Z:()=>f});var n=r(1966),i=r(9496),a=r(5924),s=r(306),o=r(4969);const l={details:"details_YVtT",isBrowser:"isBrowser_B1Ku",collapsibleContent:"collapsibleContent_mCB7"};function c(e){return!!e&&("SUMMARY"===e.tagName||c(e.parentElement))}function d(e,t){return!!e&&(e===t||d(e.parentElement,t))}function u(e){let{summary:t,children:r,...u}=e;const p=(0,s.Z)(),h=(0,i.useRef)(null),{collapsed:f,setCollapsed:m}=(0,o.u)({initialState:!u.open}),[y,g]=(0,i.useState)(u.open),w=i.isValidElement(t)?t:i.createElement("summary",null,t??"Details");return i.createElement("details",(0,n.Z)({},u,{ref:h,open:y,"data-collapsed":f,className:(0,a.Z)(l.details,p&&l.isBrowser,u.className),onMouseDown:e=>{c(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;c(t)&&d(t,h.current)&&(e.preventDefault(),f?(m(!1),g(!0)):m(!0))}}),w,i.createElement(o.z,{lazy:!1,collapsed:f,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{m(e),g(!e)}},i.createElement("div",{className:l.collapsibleContent},r)))}const p={details:"details_x2f9"},h="alert alert--info";function f(e){let{...t}=e;return i.createElement(u,(0,n.Z)({},t,{className:(0,a.Z)(h,p.details,t.className)}))}}}]); \ No newline at end of file diff --git a/assets/js/21c3df7e.50db2763.js b/assets/js/21c3df7e.50db2763.js new file mode 100644 index 00000000..fe323cea --- /dev/null +++ b/assets/js/21c3df7e.50db2763.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[440],{9613:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>v});var n=r(9496);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),d=i,v=u["".concat(c,".").concat(d)]||u[d]||m[d]||a;return r?n.createElement(v,o(o({ref:t},l),{},{components:r})):n.createElement(v,o({ref:t},l))}));function v(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(1966),i=(r(9496),r(9613));const a={sidebar_position:6},o="Usage in JavaScript",s={unversionedId:"guide/services/usage-in-javascript",id:"guide/services/usage-in-javascript",title:"Usage in JavaScript",description:"TypeDI is primarily developed for use in TypeScript.",source:"@site/docs/guide/services/usage-in-javascript.md",sourceDirName:"guide/services",slug:"/guide/services/usage-in-javascript",permalink:"/docs/guide/services/usage-in-javascript",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/usage-in-javascript.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Transient Services",permalink:"/docs/guide/services/transient-services"},next:{title:"HostContainer",permalink:"/docs/guide/services/host-container"}},c={},p=[{value:"JSService type",id:"jsservice-type",level:2},{value:"Function classes",id:"function-classes",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"usage-in-javascript"},"Usage in JavaScript"),(0,i.kt)("p",null,"TypeDI is primarily developed for use in TypeScript.\nHowever, to make it ",(0,i.kt)("em",{parentName:"p"},"easier")," to make use of it in JavaScript, a ",(0,i.kt)("a",{parentName:"p",href:"pathname:///api-reference/functions/JSService-1.html"},(0,i.kt)("inlineCode",{parentName:"a"},"JSService"))," function is provided."),(0,i.kt)("p",null,"As an example of how to use it, let's tweak the logging service we made in the ",(0,i.kt)("a",{parentName:"p",href:"/docs/examples/hello-world"},"Hello World! example"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="src/log.service.js"',title:'"src/log.service.js"'},"import { JSService } from '@freshgum/typedi';\n\nexport const LogService = JSService(\n [],\n class LogService {\n log(message) {\n console.log(message);\n }\n }\n);\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.js"',title:'"src/root.service.js"'},"import { Service } from '@freshgum/typedi';\n\nexport const RootService = JSService(\n [LogService],\n class RootService {\n public constructor(private logger) {}\n\n run() {\n this.logger.log('Hello World!');\n }\n }\n);\n")),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"As with ",(0,i.kt)("a",{parentName:"p",href:"pathname:///api-reference/functions/Service.html"},(0,i.kt)("inlineCode",{parentName:"a"},"Service")),", don't forget to place any dependencies your service requires in the array.\nOtherwise, TypeDI won't know your service requires them, and won't pass them in as arguments.")),(0,i.kt)("p",null,"As you can see, the API is quite similar to its TypeScript-friendly equivalent.\nWith our changes, the example above will run in plain JavaScript with no problems."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"But we're not done yet"),"."),(0,i.kt)("h2",{id:"jsservice-type"},(0,i.kt)("inlineCode",{parentName:"h2"},"JSService")," type"),(0,i.kt)("p",null,"In the examples above, TypeScript doesn't interpret each service as a class. That means the following will fail:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/example.ts"',title:'"src/example.ts"'},"import { LogService } from './log.service';\n// highlight-next-line-error\nconst logService: LogService = new LogService();\n// highlight-error-comment-start\n// ^^^^^^^^^^\n// 'LogService' refers to a value, but is being used as a type here. Did you mean 'typeof MyService'?\n// highlight-error-comment-end\n")),(0,i.kt)("p",null,"If you're type-checking JavaScript with TypeScript, that can quickly become a problem.\nThat's where the ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService")," ",(0,i.kt)("em",{parentName:"p"},"type")," comes in."),(0,i.kt)("p",null,"Cleverly, the ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService")," import is actually ",(0,i.kt)("em",{parentName:"p"},"two")," imports: one for the function implementation, and another for a type.\nThe type allows you to wrap the service in the type to elide type errors, like so:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/example.ts"',title:'"src/example.ts"'},"import { JSService } from '@freshgum/typedi';\nimport { LogService } from './log.service';\n\nconst logService: JSService = new LogService();\n")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Unfortunately, due to a limitation in TypeScript, it's not currently possible to export the equivalent ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService"),"-wrapped\ntype from a ",(0,i.kt)("inlineCode",{parentName:"p"},".js")," file. See ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/microsoft/TypeScript/issues/48104"},"microsoft/TypeScript#48104"),".")),(0,i.kt)("h2",{id:"function-classes"},"Function classes"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService")," function also supports functional classes as opposed to ES6 ones."),(0,i.kt)("p",null,"This lets us take advantage of TypeDI in ES5 environments without any transpilation steps."),(0,i.kt)("p",null,"As an example, let's change the ",(0,i.kt)("inlineCode",{parentName:"p"},"LogService")," we made above to the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="src/log.service.js"',title:'"src/log.service.js"'},"import { JSService } from '@freshgum/typedi';\n\nexport const LogService = JSService([], function LogService() {});\n\nLogService.prototype.log = function (message) {\n console.log(message);\n};\n")),(0,i.kt)("p",null,"We've now moved our methods outside of the main call to ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService"),".\nInstead, they reside below it."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"It's generally recommended to use ES6 classes wherever possible, as they provide\na better experience in editors such ",(0,i.kt)("a",{parentName:"p",href:"https://code.visualstudio.com/"},"Visual Studio Code"),". The example above might need additional typing in adjacent ",(0,i.kt)("inlineCode",{parentName:"p"},".d.ts")," files."),(0,i.kt)("p",{parentName:"admonition"},"As of currently, the methods in the above service are not automatically inferred by\nTypeScript. Therefore, when used, they are of type ",(0,i.kt)("inlineCode",{parentName:"p"},"any"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/21c3df7e.d6eeaef8.js b/assets/js/21c3df7e.d6eeaef8.js deleted file mode 100644 index 6b8f5513..00000000 --- a/assets/js/21c3df7e.d6eeaef8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[440],{9613:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>v});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=i,v=u["".concat(c,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(v,o(o({ref:t},l),{},{components:n})):r.createElement(v,o({ref:t},l))}));function v(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(1966),i=(n(9496),n(9613));const a={sidebar_position:6},o="Usage in JavaScript",s={unversionedId:"guide/services/usage-in-javascript",id:"guide/services/usage-in-javascript",title:"Usage in JavaScript",description:"TypeDI is primarily developed for use in TypeScript.",source:"@site/docs/guide/services/usage-in-javascript.md",sourceDirName:"guide/services",slug:"/guide/services/usage-in-javascript",permalink:"/typedi/docs/guide/services/usage-in-javascript",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/usage-in-javascript.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Transient Services",permalink:"/typedi/docs/guide/services/transient-services"},next:{title:"HostContainer",permalink:"/typedi/docs/guide/services/host-container"}},c={},p=[{value:"JSService type",id:"jsservice-type",level:2},{value:"Function classes",id:"function-classes",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"usage-in-javascript"},"Usage in JavaScript"),(0,i.kt)("p",null,"TypeDI is primarily developed for use in TypeScript.\nHowever, to make it ",(0,i.kt)("em",{parentName:"p"},"easier")," to make use of it in JavaScript, a ",(0,i.kt)("a",{parentName:"p",href:"pathname:///api-reference/functions/JSService-1.html"},(0,i.kt)("inlineCode",{parentName:"a"},"JSService"))," function is provided."),(0,i.kt)("p",null,"As an example of how to use it, let's tweak the logging service we made in the ",(0,i.kt)("a",{parentName:"p",href:"/typedi/docs/examples/hello-world"},"Hello World! example"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="src/log.service.js"',title:'"src/log.service.js"'},"import { JSService } from '@typed-inject/injector';\n\nexport const LogService = JSService(\n [],\n class LogService {\n log(message) {\n console.log(message);\n }\n }\n);\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.js"',title:'"src/root.service.js"'},"import { Service } from '@typed-inject/injector';\n\nexport const RootService = JSService(\n [LogService],\n class RootService {\n public constructor(private logger) {}\n\n run() {\n this.logger.log('Hello World!');\n }\n }\n);\n")),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"As with ",(0,i.kt)("a",{parentName:"p",href:"pathname:///api-reference/functions/Service.html"},(0,i.kt)("inlineCode",{parentName:"a"},"Service")),", don't forget to place any dependencies your service requires in the array.\nOtherwise, TypeDI won't know your service requires them, and won't pass them in as arguments.")),(0,i.kt)("p",null,"As you can see, the API is quite similar to its TypeScript-friendly equivalent.\nWith our changes, the example above will run in plain JavaScript with no problems."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"But we're not done yet"),"."),(0,i.kt)("h2",{id:"jsservice-type"},(0,i.kt)("inlineCode",{parentName:"h2"},"JSService")," type"),(0,i.kt)("p",null,"In the examples above, TypeScript doesn't interpret each service as a class. That means the following will fail:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/example.ts"',title:'"src/example.ts"'},"import { LogService } from './log.service';\n// highlight-next-line-error\nconst logService: LogService = new LogService();\n// highlight-error-comment-start\n// ^^^^^^^^^^\n// 'LogService' refers to a value, but is being used as a type here. Did you mean 'typeof MyService'?\n// highlight-error-comment-end\n")),(0,i.kt)("p",null,"If you're type-checking JavaScript with TypeScript, that can quickly become a problem.\nThat's where the ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService")," ",(0,i.kt)("em",{parentName:"p"},"type")," comes in."),(0,i.kt)("p",null,"Cleverly, the ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService")," import is actually ",(0,i.kt)("em",{parentName:"p"},"two")," imports: one for the function implementation, and another for a type.\nThe type allows you to wrap the service in the type to elide type errors, like so:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/example.ts"',title:'"src/example.ts"'},"import { JSService } from '@typed-inject/injector';\nimport { LogService } from './log.service';\n\nconst logService: JSService = new LogService();\n")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Unfortunately, due to a limitation in TypeScript, it's not currently possible to export the equivalent ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService"),"-wrapped\ntype from a ",(0,i.kt)("inlineCode",{parentName:"p"},".js")," file. See ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/microsoft/TypeScript/issues/48104"},"microsoft/TypeScript#48104"),".")),(0,i.kt)("h2",{id:"function-classes"},"Function classes"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService")," function also supports functional classes as opposed to ES6 ones."),(0,i.kt)("p",null,"This lets us take advantage of TypeDI in ES5 environments without any transpilation steps."),(0,i.kt)("p",null,"As an example, let's change the ",(0,i.kt)("inlineCode",{parentName:"p"},"LogService")," we made above to the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="src/log.service.js"',title:'"src/log.service.js"'},"import { JSService } from '@typed-inject/injector';\n\nexport const LogService = JSService([], function LogService() {});\n\nLogService.prototype.log = function (message) {\n console.log(message);\n};\n")),(0,i.kt)("p",null,"We've now moved our methods outside of the main call to ",(0,i.kt)("inlineCode",{parentName:"p"},"JSService"),".\nInstead, they reside below it."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"It's generally recommended to use ES6 classes wherever possible, as they provide\na better experience in editors such ",(0,i.kt)("a",{parentName:"p",href:"https://code.visualstudio.com/"},"Visual Studio Code"),". The example above might need additional typing in adjacent ",(0,i.kt)("inlineCode",{parentName:"p"},".d.ts")," files."),(0,i.kt)("p",{parentName:"admonition"},"As of currently, the methods in the above service are not automatically inferred by\nTypeScript. Therefore, when used, they are of type ",(0,i.kt)("inlineCode",{parentName:"p"},"any"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3021cf83.d7459cdf.js b/assets/js/3021cf83.3c388bdd.js similarity index 88% rename from assets/js/3021cf83.d7459cdf.js rename to assets/js/3021cf83.3c388bdd.js index 72c81c8d..8070b599 100644 --- a/assets/js/3021cf83.d7459cdf.js +++ b/assets/js/3021cf83.3c388bdd.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[538],{9613:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(9496);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),p=i(r),m=a,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var u={};for(var s in t)hasOwnProperty.call(t,s)&&(u[s]=t[s]);u.originalType=e,u[p]="string"==typeof e?e:a,l[1]=u;for(var i=2;i{r.d(t,{Z:()=>l});var n=r(9496),a=r(5924);const o={tabItem:"tabItem_Dm1u"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4159:(e,t,r)=>{r.d(t,{Z:()=>w});var n=r(1966),a=r(9496),o=r(5924),l=r(4269),u=r(3442),s=r(5399),i=r(2922),c=r(671);function p(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function d(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??p(r);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,u.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:t,groupId:r});return[(0,s._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function b(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=d(e),[l,u]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[s,i]=f({queryString:r,groupId:n}),[p,b]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),g=(()=>{const e=s??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{g&&u(g)}),[g]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);u(e),i(e),b(e)}),[i,b,o]),tabValues:o}}var g=r(306);const y={tabList:"tabList_duBI",tabItem:"tabItem_p83j"};function h(e){let{className:t,block:r,selectedValue:u,selectValue:s,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==u&&(p(t),s(n))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:u===t?0:-1,"aria-selected":u===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",y.tabItem,l?.className,{"tabs__item--active":u===t})}),r??t)})))}function v(e){let{lazy:t,children:r,selectedValue:n}=e;const o=(Array.isArray(r)?r:[r]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function k(e){const t=b(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",y.tabList)},a.createElement(h,(0,n.Z)({},e,t)),a.createElement(v,(0,n.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return a.createElement(k,(0,n.Z)({key:String(t)},e))}},5052:(e,t,r)=>{r.d(t,{Z:()=>s});var n=r(9496),a=r(8517),o=r(4159),l=r(2274);const u=[{name:"NPM",format(e){let{packageName:t,global:r}=e;const n=[];r&&n.push("-g");let a=`npm install ${t}`;return n.length>0&&(a+=` ${n.join(" ")}`),a},storageKey:"npm"},{name:"Yarn",format(e){let{packageName:t,global:r}=e;return r?`yarn global add ${t}`:`yarn add ${t}`},storageKey:"yarn"},{name:"PNPM",format:e=>`p${u[0].format(e)}`,storageKey:"pnpm"}];function s(e){return n.createElement(o.Z,{groupId:"package_manager",children:u.map((function(t){const{storageKey:r,format:o,name:u}=t,s=o(e);return n.createElement(l.Z,{value:r,label:u,key:r},n.createElement(a.Z,null,"$ ",s))}))})}},5747:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var n=r(1966),a=(r(9496),r(9613)),o=r(5052);const l={sidebar_position:1},u="Getting Started",s={unversionedId:"getting-started",id:"getting-started",title:"Getting Started",description:"Welcome to the TypeDI documentation! To get started, you'll need to ensure you have a working",source:"@site/docs/getting-started.mdx",sourceDirName:".",slug:"/getting-started",permalink:"/typedi/docs/getting-started",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/getting-started.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Examples"}},i={},c=[],p={toc:c},d="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"getting-started"},"Getting Started"),(0,a.kt)("p",null,"Welcome to the TypeDI documentation! To get started, you'll need to ensure you have a working\nenvironment containing Node and NPM (or any other package manager)."),(0,a.kt)("p",null,"Then, you'll need to install TypeDI:"),(0,a.kt)(o.Z,{packageName:"@typed-inject/injector",mdxType:"NPMInstallBlock"}),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"You're done!")," Move on to the ",(0,a.kt)("a",{parentName:"p",href:"./examples/hello-world"},"Hello World!")," example to learn how to use TypeDI."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[538],{9613:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(9496);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),p=i(r),m=a,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var u={};for(var s in t)hasOwnProperty.call(t,s)&&(u[s]=t[s]);u.originalType=e,u[p]="string"==typeof e?e:a,l[1]=u;for(var i=2;i{r.d(t,{Z:()=>l});var n=r(9496),a=r(5924);const o={tabItem:"tabItem_Dm1u"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4159:(e,t,r)=>{r.d(t,{Z:()=>w});var n=r(1966),a=r(9496),o=r(5924),l=r(4269),u=r(3442),s=r(5399),i=r(2922),c=r(671);function p(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function d(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??p(r);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,u.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:t,groupId:r});return[(0,s._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function b(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=d(e),[l,u]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[s,i]=f({queryString:r,groupId:n}),[p,b]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),g=(()=>{const e=s??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{g&&u(g)}),[g]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);u(e),i(e),b(e)}),[i,b,o]),tabValues:o}}var g=r(306);const y={tabList:"tabList_duBI",tabItem:"tabItem_p83j"};function h(e){let{className:t,block:r,selectedValue:u,selectValue:s,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==u&&(p(t),s(n))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:u===t?0:-1,"aria-selected":u===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",y.tabItem,l?.className,{"tabs__item--active":u===t})}),r??t)})))}function v(e){let{lazy:t,children:r,selectedValue:n}=e;const o=(Array.isArray(r)?r:[r]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function k(e){const t=b(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",y.tabList)},a.createElement(h,(0,n.Z)({},e,t)),a.createElement(v,(0,n.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return a.createElement(k,(0,n.Z)({key:String(t)},e))}},5052:(e,t,r)=>{r.d(t,{Z:()=>s});var n=r(9496),a=r(8517),o=r(4159),l=r(2274);const u=[{name:"NPM",format(e){let{packageName:t,global:r}=e;const n=[];r&&n.push("-g");let a=`npm install ${t}`;return n.length>0&&(a+=` ${n.join(" ")}`),a},storageKey:"npm"},{name:"Yarn",format(e){let{packageName:t,global:r}=e;return r?`yarn global add ${t}`:`yarn add ${t}`},storageKey:"yarn"},{name:"PNPM",format:e=>`p${u[0].format(e)}`,storageKey:"pnpm"}];function s(e){return n.createElement(o.Z,{groupId:"package_manager",children:u.map((function(t){const{storageKey:r,format:o,name:u}=t,s=o(e);return n.createElement(l.Z,{value:r,label:u,key:r},n.createElement(a.Z,null,"$ ",s))}))})}},5747:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var n=r(1966),a=(r(9496),r(9613)),o=r(5052);const l={sidebar_position:1},u="Getting Started",s={unversionedId:"getting-started",id:"getting-started",title:"Getting Started",description:"Welcome to the TypeDI documentation! To get started, you'll need to ensure you have a working",source:"@site/docs/getting-started.mdx",sourceDirName:".",slug:"/getting-started",permalink:"/docs/getting-started",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/getting-started.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Examples"}},i={},c=[],p={toc:c},d="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"getting-started"},"Getting Started"),(0,a.kt)("p",null,"Welcome to the TypeDI documentation! To get started, you'll need to ensure you have a working\nenvironment containing Node and NPM (or any other package manager)."),(0,a.kt)("p",null,"Then, you'll need to install TypeDI:"),(0,a.kt)(o.Z,{packageName:"@freshgum/typedi",mdxType:"NPMInstallBlock"}),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"You're done!")," Move on to the ",(0,a.kt)("a",{parentName:"p",href:"./examples/hello-world"},"Hello World!")," example to learn how to use TypeDI."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3334719e.e92460df.js b/assets/js/3334719e.ef315589.js similarity index 57% rename from assets/js/3334719e.e92460df.js rename to assets/js/3334719e.ef315589.js index a82ae5d6..b6b9c1af 100644 --- a/assets/js/3334719e.e92460df.js +++ b/assets/js/3334719e.ef315589.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[300],{9613:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>v});var n=r(9496);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,p=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,v=d["".concat(p,".").concat(m)]||d[m]||u[m]||s;return r?n.createElement(v,a(a({ref:t},l),{},{components:r})):n.createElement(v,a({ref:t},l))}));function v(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=r.length,a=new Array(s);a[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[d]="string"==typeof e?e:o,a[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=r(1966),o=(r(9496),r(9613));const s={sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},a="Stopping Our App",i={unversionedId:"examples/nodejs-web-server/application-disposal",id:"examples/nodejs-web-server/application-disposal",title:"Stopping Our App",description:"Our WebServerService is pretty smart. It creates a server for us on-demand,",source:"@site/docs/examples/nodejs-web-server/application-disposal.md",sourceDirName:"examples/nodejs-web-server",slug:"/examples/nodejs-web-server/application-disposal",permalink:"/typedi/docs/examples/nodejs-web-server/application-disposal",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/nodejs-web-server/application-disposal.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"NodeJS Web Server",permalink:"/typedi/docs/examples/nodejs-web-server/implementation"},next:{title:"Adding Testing",permalink:"/typedi/docs/examples/nodejs-web-server/testing"}},p={},c=[],l={toc:c},d="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"stopping-our-app"},"Stopping Our App"),(0,o.kt)("p",null,"Our ",(0,o.kt)("inlineCode",{parentName:"p"},"WebServerService")," is pretty smart. It creates a server for us on-demand,\nwhile also handling any requests from users on the server's port."),(0,o.kt)("p",null,"However, one thing it doesn't do is allow the consumer to shut ",(0,o.kt)("em",{parentName:"p"},"down")," the server.\nCurrently, the only way to do this is to stop the Node.js process altogether."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"This is an anti-pattern; services should ",(0,o.kt)("em",{parentName:"p"},"always")," provide a way to close down\nany resources they may create over their lifetime. For example, a service\nmanaging database connections should allow for the closing of connections too.")),(0,o.kt)("p",null,"Let's update our web server service to provide a ",(0,o.kt)("inlineCode",{parentName:"p"},"shutdown")," method, which will\nshutdown the active HTTP server."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'src="webserver.service.ts"',src:'"webserver.service.ts"'},"// ...\n\n@Service([DatabaseService])\nclass WebServerService {\n // ...\n // highlight-revision-start\n stopServer() {\n if (this.server?.listening) {\n this.server.close();\n }\n }\n // highlight-revision-end\n // ...\n}\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[300],{9613:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>v});var n=r(9496);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,p=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,v=d["".concat(p,".").concat(m)]||d[m]||u[m]||s;return r?n.createElement(v,a(a({ref:t},l),{},{components:r})):n.createElement(v,a({ref:t},l))}));function v(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=r.length,a=new Array(s);a[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[d]="string"==typeof e?e:o,a[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=r(1966),o=(r(9496),r(9613));const s={sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},a="Stopping Our App",i={unversionedId:"examples/nodejs-web-server/application-disposal",id:"examples/nodejs-web-server/application-disposal",title:"Stopping Our App",description:"Our WebServerService is pretty smart. It creates a server for us on-demand,",source:"@site/docs/examples/nodejs-web-server/application-disposal.md",sourceDirName:"examples/nodejs-web-server",slug:"/examples/nodejs-web-server/application-disposal",permalink:"/docs/examples/nodejs-web-server/application-disposal",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/nodejs-web-server/application-disposal.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"NodeJS Web Server",permalink:"/docs/examples/nodejs-web-server/implementation"},next:{title:"Adding Testing",permalink:"/docs/examples/nodejs-web-server/testing"}},p={},c=[],l={toc:c},d="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"stopping-our-app"},"Stopping Our App"),(0,o.kt)("p",null,"Our ",(0,o.kt)("inlineCode",{parentName:"p"},"WebServerService")," is pretty smart. It creates a server for us on-demand,\nwhile also handling any requests from users on the server's port."),(0,o.kt)("p",null,"However, one thing it doesn't do is allow the consumer to shut ",(0,o.kt)("em",{parentName:"p"},"down")," the server.\nCurrently, the only way to do this is to stop the Node.js process altogether."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"This is an anti-pattern; services should ",(0,o.kt)("em",{parentName:"p"},"always")," provide a way to close down\nany resources they may create over their lifetime. For example, a service\nmanaging database connections should allow for the closing of connections too.")),(0,o.kt)("p",null,"Let's update our web server service to provide a ",(0,o.kt)("inlineCode",{parentName:"p"},"shutdown")," method, which will\nshutdown the active HTTP server."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'src="webserver.service.ts"',src:'"webserver.service.ts"'},"// ...\n\n@Service([DatabaseService])\nclass WebServerService {\n // ...\n // highlight-revision-start\n stopServer() {\n if (this.server?.listening) {\n this.server.close();\n }\n }\n // highlight-revision-end\n // ...\n}\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/37e83d0a.b9c42019.js b/assets/js/37e83d0a.b9c42019.js new file mode 100644 index 00000000..9f838caa --- /dev/null +++ b/assets/js/37e83d0a.b9c42019.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[302],{5474:(e,t,n)=>{n.d(t,{Z:()=>a});var i=n(9496),o=n(8517);function a(e){const{title:t}=e;if(t?.startsWith('"')&&!t?.endsWith('"'))throw new Error(`Unterminated quote detected in code-block: ${t}.`);return i.createElement(i.Fragment,null,i.createElement(o.Z,e))}},1103:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var i=n(1966),o=(n(9496),n(9613)),a=(n(5474),n(1362));const r={sidebar_position:4},s="Resolution Constraints",l={unversionedId:"guide/services/resolution-constraints",id:"guide/services/resolution-constraints",title:"Resolution Constraints",description:"Many times, you'll want a service to rely on a dependency, but there's always",source:"@site/docs/guide/services/resolution-constraints.mdx",sourceDirName:"guide/services",slug:"/guide/services/resolution-constraints",permalink:"/docs/guide/services/resolution-constraints",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/resolution-constraints.mdx",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Multiple Services",permalink:"/docs/guide/services/multiple-services"},next:{title:"Singletons",permalink:"/docs/guide/services/singletons"}},c={},p=[{value:"Introduction",id:"introduction",level:2},{value:"Resolution Constraint Flags",id:"resolution-constraint-flags",level:2},{value:"Making dependencies optional with Optional()",id:"making-dependencies-optional-with-optional",level:2},{value:"Resolve via the container's parent with SkipSelf()",id:"resolve-via-the-containers-parent-with-skipself",level:2},{value:"Resolve non-recursively with Self()",id:"resolve-non-recursively-with-self",level:2},{value:"Acquire multiple services with Many()",id:"acquire-multiple-services-with-many",level:2}],u={toc:p},d="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(d,(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resolution-constraints"},"Resolution Constraints"),(0,o.kt)("p",null,"Many times, you'll want a service to rely on a dependency, but there's always\nthe possibility of it not existing (and you wouldn't want your service to fail if it didn't)."),(0,o.kt)("p",null,"Or, you want to take advantage of ",(0,o.kt)("a",{parentName:"p",href:"../containers/introduction#container-inheritance"},"container inheritance"),"\nand resolve a symbol in the context of the current parent's container, or restrict the\nresolution process to return ",(0,o.kt)("inlineCode",{parentName:"p"},"null")," if the ",(0,o.kt)("em",{parentName:"p"},"current")," container doesn't have it."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"(There are more features too.)")),(0,o.kt)("hr",null),(0,o.kt)("p",null,"This is where ",(0,o.kt)("em",{parentName:"p"},"resolution constraints")," shine. They allow you to specify how you'd like a certain\ndependency to be resolved, by a set-list of pre-defined strategies."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"This feature is ",(0,o.kt)("em",{parentName:"p"},"very")," similar to ",(0,o.kt)("a",{parentName:"p",href:"https://angular.io/guide/dependency-injection-in-action#qualify-dependency-lookup-with-parameter-decorators"},"Angular's DI decorators"),".\nIn fact, resolution constraints ",(0,o.kt)("em",{parentName:"p"},"were")," originally designed to mimic these features in TypeDI."),(0,o.kt)("p",{parentName:"admonition"},"Therefore, if you're familiar with Angular, you most likely already\nunderstand resolution constraints.")),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"When a service requests an identifier (which can be another service or a token) as a dependency,\nthe Dependency Injection framework has to check its internal map for that identifier and, if found,\nreturn an instance of that value.",(0,o.kt)("br",{parentName:"p"}),"\n","If the identifier cannot be found, it checks its parent, which checks its parent (recursively)\nuntil the chain is exhausted. An error is then thrown."),(0,o.kt)("details",null,(0,o.kt)("summary",null,"If you're a visual learner, here's a flow-chart of the process."),(0,o.kt)(a.Z,{value:'\nflowchart\n\t1("A service is requested \nfrom the container.") --\x3e 704938("Lookup the item\nin the container.")\n\t704938 --\x3e 627865{"Was it\nfound?"}\n\t627865 ---|"Yes"| 326567("Return value.")\n\t627865 ---|"No"| 392131{"Does container\nhave parent?"}\n\t392131 ---|"No"| 415873("Throw error.")\n\t392131 ---|"Yes"| 924841("Set container to\nparent container.")\n\t924841 --- 704938\n',mdxType:"Mermaid"})),(0,o.kt)("p",null,"While this behaviour makes sense for most configurations, there are most certainly times when you'll\nwant to modify it a little. In the below sections, we'll explore how to do that in TypeDI."),(0,o.kt)("h2",{id:"resolution-constraint-flags"},"Resolution Constraint Flags"),(0,o.kt)("p",null,"In TypeDI, the concept of constraining certain resolutions is done through specific functions which,\nwhen called, return a ",(0,o.kt)("em",{parentName:"p"},"bit"),". Multiple functions can be conjoined with the ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR"},"Bitwise OR"),"\noperator to form a bitmask, like so:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"Optional() | Many() | Self()\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"You don't have to understand how bitmasks work to make use of resolution constraints.\nThe functions above construct the bitmask for you, which can then be safely passed to TypeDI.")),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"You should always make use of the above functions instead of constructing a bitmask yourself,\nas the signature of the mask could change at any time.")),(0,o.kt)("h2",{id:"making-dependencies-optional-with-optional"},"Making dependencies optional with ",(0,o.kt)("inlineCode",{parentName:"h2"},"Optional()")),(0,o.kt)("p",null,"If your service ",(0,o.kt)("em",{parentName:"p"},"wants")," a dependency, but doesn't ",(0,o.kt)("em",{parentName:"p"},"need")," it, you can make use of the ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional()")," flag.\nIf the identifier cannot be found, the value will be substituted with ",(0,o.kt)("inlineCode",{parentName:"p"},"null"),". ",(0,o.kt)("em",{parentName:"p"},"(This would be useful if you were,\nfor example, building a library where some parts of the configuration might not have been set-up by the end-user.)")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Adding an optinal constraint isn't always necessary: only add it if you're not 100% sure that\nthe service you're using as a dependency will not be available at runtime.")),(0,o.kt)("p",null,"Let's explore how we could make use of ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional")," in an example service, which\nrequests an identifier from the container that may not exist."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/configuration-reader.service.ts"',title:'"src/configuration-reader.service.ts"'},"import { Service, Optional } from '@freshgum/typedi';\nimport { APP_TOKEN } from './configuration'; // Where APP_TOKEN is a Token.\n\n@Service([\n [APP_TOKEN, Optional()]\n])\nexport class ConfigurationReaderService {\n constructor (private appToken: string | null) { }\n\n validateConfiguration () {\n if (this.appToken === null) {\n console.warn('An app token was not provided!');\n }\n }\n}\n")),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"If you're using an optional service, make sure you also allow the type\nto be null (like above, where we used ",(0,o.kt)("inlineCode",{parentName:"p"},"| null"),")\nOtherwise in usage, you may forget that the value may not exist, causing runtime errors.")),(0,o.kt)("p",null,"In the above service, we requested ",(0,o.kt)("inlineCode",{parentName:"p"},"APP_TOKEN")," as a dependency.\nIn the case of our library, this would be set by the user before they start the root service."),(0,o.kt)("p",null,"However, if that value isn't set, we log a warning to the console."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Normally, if ",(0,o.kt)("inlineCode",{parentName:"em"},"APP_TOKEN")," wasn't present in the container, the container itself would throw an error.")),(0,o.kt)("h2",{id:"resolve-via-the-containers-parent-with-skipself"},"Resolve via the container's parent with ",(0,o.kt)("inlineCode",{parentName:"h2"},"SkipSelf()")),(0,o.kt)("p",null,"Much like in Angular, the ",(0,o.kt)("inlineCode",{parentName:"p"},"SkipSelf")," can be applied to individual dependencies\nto tell the container to resolve them from its parent container."),(0,o.kt)("p",null,"This can be useful in the case of an application which makes use of container\ninheritance to provide a different set of tokens to services under it."),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Use of ",(0,o.kt)("inlineCode",{parentName:"p"},"SkipSelf")," makes your services dependent on a certain container structure.\nIf you were to change that structure, resolutions may fail, leading to runtime errors.\nUse it carefully.")),(0,o.kt)("p",null,"For instance, consider the following example of an blog.\nThe application creates a ",(0,o.kt)("inlineCode",{parentName:"p"},"Page")," service for each page of the blog.\nEach ",(0,o.kt)("inlineCode",{parentName:"p"},"Page")," service has access to the ",(0,o.kt)("inlineCode",{parentName:"p"},"DOM_NODE")," token, which:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"in the child container the ",(0,o.kt)("inlineCode",{parentName:"li"},"Page")," is run in, is set to the DOM element containing the individual page."),(0,o.kt)("li",{parentName:"ul"},"in the parent container, is set to the ",(0,o.kt)("inlineCode",{parentName:"li"},"body")," element.")),(0,o.kt)("p",null,'Each page contains a dark mode button which, when clicked,\ntoggles the "dark-mode" class on the ',(0,o.kt)("inlineCode",{parentName:"p"},"")," element."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/dom-node.token.ts"',title:'"src/dom-node.token.ts"'},"import { Token } from '@freshgum/typedi';\n\nexport const DOM_NODE = new Token(`\\\nThe current DOM node. In services for individual pages,\nthis will be set to the node of the page element.\nIn the root, this will be set to the body of the document.\n`);\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/page.service.ts"',title:'"src/page.service.ts"'},"import { Service, SkipSelf } from '@freshgum/typedi';\nimport { STORAGE } from './storage.token';\n\n@Service([\n DOM_NODE,\n [DOM_NODE, SkipSelf()]\n])\nexport class PageService {\n constructor (private pageNode: HTMLElement, private rootNode: HTMLElement) { }\n\n bootstrap () {\n this.pageNode.getElementById('dark-mode-button').addEventListener('click', () => {\n this.rootNode.classList.toggle('dark-mode');\n });\n }\n}\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { ContainerInstance, Service, HostContainer } from '@freshgum/typedi';\nimport { PageService } from './page.service';\nimport { route } from 'my-router'; // Placeholder for your router :-)\n\n@Service([\n HostContainer()\n])\nexport class RootService {\n constructor (private container: ContainerInstance) {\n container.set({ id: DOM_NODE, value: document.body, dependencies: [ ] });\n }\n\n async renderPage (pageUrl: string) {\n const childContainer = this.container.ofChild(Symbol('page'));\n const { renderedElement } = await route(pageUrl);\n childDontainer.set({ id: DOM_NODE, value: renderedElement, dependencies: [ ] });\n childContainer.get(PageService).bootstrap();\n }\n}\n\nconst root = Container.get(RootService);\nroot.renderPage('/introduction');\n")),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"(While this is a rather contrived example, it serves as a guide for how to use the constraint.)")),(0,o.kt)("h2",{id:"resolve-non-recursively-with-self"},"Resolve non-recursively with ",(0,o.kt)("inlineCode",{parentName:"h2"},"Self()")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Self")," constraint allows you to tell the container ",(0,o.kt)("em",{parentName:"p"},"not")," to traverse up the container\nparent tree until it finds a value."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"This constraint is most useful when combined with ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional"),".\nThat way, if the current container doesn't have the value, a runtime error would not occur.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"If you're a visual learner, here's a flow-chart of the resolution process with ",(0,o.kt)("code",null,"Self"),"."),(0,o.kt)("p",null,"If we were to modify our flow-chart from above, the resolution for resolving identifiers marked with ",(0,o.kt)("code",null,"Self")," would look like this:"),(0,o.kt)(a.Z,{value:'\nflowchart\n\t1("A service is requested \nfrom the container.") --\x3e 704938("Lookup the item\nin the container.")\n\t704938 --\x3e 627865{"Was it\nfound?"}\n\t627865 ---|"Yes"| 326567("Return value.")\n\t627865 ---|"No"| 415873("Throw error.")\n',mdxType:"Mermaid"})),(0,o.kt)("h2",{id:"acquire-multiple-services-with-many"},"Acquire multiple services with ",(0,o.kt)("inlineCode",{parentName:"h2"},"Many()")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Many")," constraint is functionally equivalent to ",(0,o.kt)("inlineCode",{parentName:"p"},"Container.getMany"),".\nIt can also be combined with ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"SkipSelf")," (or ",(0,o.kt)("inlineCode",{parentName:"p"},"Self"),") to further constrain resolution."),(0,o.kt)("p",null,"To provide an example of this, consider the following:"),(0,o.kt)("p",null,"XXX"))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/37e83d0a.df8013bf.js b/assets/js/37e83d0a.df8013bf.js deleted file mode 100644 index 8f8484de..00000000 --- a/assets/js/37e83d0a.df8013bf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[302],{5474:(e,t,n)=>{n.d(t,{Z:()=>a});var i=n(9496),o=n(8517);function a(e){const{title:t}=e;if(t?.startsWith('"')&&!t?.endsWith('"'))throw new Error(`Unterminated quote detected in code-block: ${t}.`);return i.createElement(i.Fragment,null,i.createElement(o.Z,e))}},1103:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var i=n(1966),o=(n(9496),n(9613)),a=(n(5474),n(1362));const r={sidebar_position:4},s="Resolution Constraints",l={unversionedId:"guide/services/resolution-constraints",id:"guide/services/resolution-constraints",title:"Resolution Constraints",description:"Many times, you'll want a service to rely on a dependency, but there's always",source:"@site/docs/guide/services/resolution-constraints.mdx",sourceDirName:"guide/services",slug:"/guide/services/resolution-constraints",permalink:"/typedi/docs/guide/services/resolution-constraints",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/resolution-constraints.mdx",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Multiple Services",permalink:"/typedi/docs/guide/services/multiple-services"},next:{title:"Singletons",permalink:"/typedi/docs/guide/services/singletons"}},c={},p=[{value:"Introduction",id:"introduction",level:2},{value:"Resolution Constraint Flags",id:"resolution-constraint-flags",level:2},{value:"Making dependencies optional with Optional()",id:"making-dependencies-optional-with-optional",level:2},{value:"Resolve via the container's parent with SkipSelf()",id:"resolve-via-the-containers-parent-with-skipself",level:2},{value:"Resolve non-recursively with Self()",id:"resolve-non-recursively-with-self",level:2},{value:"Acquire multiple services with Many()",id:"acquire-multiple-services-with-many",level:2}],u={toc:p},d="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(d,(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resolution-constraints"},"Resolution Constraints"),(0,o.kt)("p",null,"Many times, you'll want a service to rely on a dependency, but there's always\nthe possibility of it not existing (and you wouldn't want your service to fail if it didn't)."),(0,o.kt)("p",null,"Or, you want to take advantage of ",(0,o.kt)("a",{parentName:"p",href:"../containers/introduction#container-inheritance"},"container inheritance"),"\nand resolve a symbol in the context of the current parent's container, or restrict the\nresolution process to return ",(0,o.kt)("inlineCode",{parentName:"p"},"null")," if the ",(0,o.kt)("em",{parentName:"p"},"current")," container doesn't have it."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"(There are more features too.)")),(0,o.kt)("hr",null),(0,o.kt)("p",null,"This is where ",(0,o.kt)("em",{parentName:"p"},"resolution constraints")," shine. They allow you to specify how you'd like a certain\ndependency to be resolved, by a set-list of pre-defined strategies."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"This feature is ",(0,o.kt)("em",{parentName:"p"},"very")," similar to ",(0,o.kt)("a",{parentName:"p",href:"https://angular.io/guide/dependency-injection-in-action#qualify-dependency-lookup-with-parameter-decorators"},"Angular's DI decorators"),".\nIn fact, resolution constraints ",(0,o.kt)("em",{parentName:"p"},"were")," originally designed to mimic these features in TypeDI."),(0,o.kt)("p",{parentName:"admonition"},"Therefore, if you're familiar with Angular, you most likely already\nunderstand resolution constraints.")),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"When a service requests an identifier (which can be another service or a token) as a dependency,\nthe Dependency Injection framework has to check its internal map for that identifier and, if found,\nreturn an instance of that value.",(0,o.kt)("br",{parentName:"p"}),"\n","If the identifier cannot be found, it checks its parent, which checks its parent (recursively)\nuntil the chain is exhausted. An error is then thrown."),(0,o.kt)("details",null,(0,o.kt)("summary",null,"If you're a visual learner, here's a flow-chart of the process."),(0,o.kt)(a.Z,{value:'\nflowchart\n\t1("A service is requested \nfrom the container.") --\x3e 704938("Lookup the item\nin the container.")\n\t704938 --\x3e 627865{"Was it\nfound?"}\n\t627865 ---|"Yes"| 326567("Return value.")\n\t627865 ---|"No"| 392131{"Does container\nhave parent?"}\n\t392131 ---|"No"| 415873("Throw error.")\n\t392131 ---|"Yes"| 924841("Set container to\nparent container.")\n\t924841 --- 704938\n',mdxType:"Mermaid"})),(0,o.kt)("p",null,"While this behaviour makes sense for most configurations, there are most certainly times when you'll\nwant to modify it a little. In the below sections, we'll explore how to do that in TypeDI."),(0,o.kt)("h2",{id:"resolution-constraint-flags"},"Resolution Constraint Flags"),(0,o.kt)("p",null,"In TypeDI, the concept of constraining certain resolutions is done through specific functions which,\nwhen called, return a ",(0,o.kt)("em",{parentName:"p"},"bit"),". Multiple functions can be conjoined with the ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR"},"Bitwise OR"),"\noperator to form a bitmask, like so:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"Optional() | Many() | Self()\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"You don't have to understand how bitmasks work to make use of resolution constraints.\nThe functions above construct the bitmask for you, which can then be safely passed to TypeDI.")),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"You should always make use of the above functions instead of constructing a bitmask yourself,\nas the signature of the mask could change at any time.")),(0,o.kt)("h2",{id:"making-dependencies-optional-with-optional"},"Making dependencies optional with ",(0,o.kt)("inlineCode",{parentName:"h2"},"Optional()")),(0,o.kt)("p",null,"If your service ",(0,o.kt)("em",{parentName:"p"},"wants")," a dependency, but doesn't ",(0,o.kt)("em",{parentName:"p"},"need")," it, you can make use of the ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional()")," flag.\nIf the identifier cannot be found, the value will be substituted with ",(0,o.kt)("inlineCode",{parentName:"p"},"null"),". ",(0,o.kt)("em",{parentName:"p"},"(This would be useful if you were,\nfor example, building a library where some parts of the configuration might not have been set-up by the end-user.)")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Adding an optinal constraint isn't always necessary: only add it if you're not 100% sure that\nthe service you're using as a dependency will not be available at runtime.")),(0,o.kt)("p",null,"Let's explore how we could make use of ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional")," in an example service, which\nrequests an identifier from the container that may not exist."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/configuration-reader.service.ts"',title:'"src/configuration-reader.service.ts"'},"import { Service, Optional } from '@typed-inject/injector';\nimport { APP_TOKEN } from './configuration'; // Where APP_TOKEN is a Token.\n\n@Service([\n [APP_TOKEN, Optional()]\n])\nexport class ConfigurationReaderService {\n constructor (private appToken: string | null) { }\n\n validateConfiguration () {\n if (this.appToken === null) {\n console.warn('An app token was not provided!');\n }\n }\n}\n")),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"If you're using an optional service, make sure you also allow the type\nto be null (like above, where we used ",(0,o.kt)("inlineCode",{parentName:"p"},"| null"),")\nOtherwise in usage, you may forget that the value may not exist, causing runtime errors.")),(0,o.kt)("p",null,"In the above service, we requested ",(0,o.kt)("inlineCode",{parentName:"p"},"APP_TOKEN")," as a dependency.\nIn the case of our library, this would be set by the user before they start the root service."),(0,o.kt)("p",null,"However, if that value isn't set, we log a warning to the console."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Normally, if ",(0,o.kt)("inlineCode",{parentName:"em"},"APP_TOKEN")," wasn't present in the container, the container itself would throw an error.")),(0,o.kt)("h2",{id:"resolve-via-the-containers-parent-with-skipself"},"Resolve via the container's parent with ",(0,o.kt)("inlineCode",{parentName:"h2"},"SkipSelf()")),(0,o.kt)("p",null,"Much like in Angular, the ",(0,o.kt)("inlineCode",{parentName:"p"},"SkipSelf")," can be applied to individual dependencies\nto tell the container to resolve them from its parent container."),(0,o.kt)("p",null,"This can be useful in the case of an application which makes use of container\ninheritance to provide a different set of tokens to services under it."),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Use of ",(0,o.kt)("inlineCode",{parentName:"p"},"SkipSelf")," makes your services dependent on a certain container structure.\nIf you were to change that structure, resolutions may fail, leading to runtime errors.\nUse it carefully.")),(0,o.kt)("p",null,"For instance, consider the following example of an blog.\nThe application creates a ",(0,o.kt)("inlineCode",{parentName:"p"},"Page")," service for each page of the blog.\nEach ",(0,o.kt)("inlineCode",{parentName:"p"},"Page")," service has access to the ",(0,o.kt)("inlineCode",{parentName:"p"},"DOM_NODE")," token, which:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"in the child container the ",(0,o.kt)("inlineCode",{parentName:"li"},"Page")," is run in, is set to the DOM element containing the individual page."),(0,o.kt)("li",{parentName:"ul"},"in the parent container, is set to the ",(0,o.kt)("inlineCode",{parentName:"li"},"body")," element.")),(0,o.kt)("p",null,'Each page contains a dark mode button which, when clicked,\ntoggles the "dark-mode" class on the ',(0,o.kt)("inlineCode",{parentName:"p"},"")," element."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/dom-node.token.ts"',title:'"src/dom-node.token.ts"'},"import { Token } from '@typed-inject/injector';\n\nexport const DOM_NODE = new Token(`\\\nThe current DOM node. In services for individual pages,\nthis will be set to the node of the page element.\nIn the root, this will be set to the body of the document.\n`);\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/page.service.ts"',title:'"src/page.service.ts"'},"import { Service, SkipSelf } from '@typed-inject/injector';\nimport { STORAGE } from './storage.token';\n\n@Service([\n DOM_NODE,\n [DOM_NODE, SkipSelf()]\n])\nexport class PageService {\n constructor (private pageNode: HTMLElement, private rootNode: HTMLElement) { }\n\n bootstrap () {\n this.pageNode.getElementById('dark-mode-button').addEventListener('click', () => {\n this.rootNode.classList.toggle('dark-mode');\n });\n }\n}\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { ContainerInstance, Service, HostContainer } from '@typed-inject/injector';\nimport { PageService } from './page.service';\nimport { route } from 'my-router'; // Placeholder for your router :-)\n\n@Service([\n HostContainer()\n])\nexport class RootService {\n constructor (private container: ContainerInstance) {\n container.set({ id: DOM_NODE, value: document.body, dependencies: [ ] });\n }\n\n async renderPage (pageUrl: string) {\n const childContainer = this.container.ofChild(Symbol('page'));\n const { renderedElement } = await route(pageUrl);\n childDontainer.set({ id: DOM_NODE, value: renderedElement, dependencies: [ ] });\n childContainer.get(PageService).bootstrap();\n }\n}\n\nconst root = Container.get(RootService);\nroot.renderPage('/introduction');\n")),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"(While this is a rather contrived example, it serves as a guide for how to use the constraint.)")),(0,o.kt)("h2",{id:"resolve-non-recursively-with-self"},"Resolve non-recursively with ",(0,o.kt)("inlineCode",{parentName:"h2"},"Self()")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Self")," constraint allows you to tell the container ",(0,o.kt)("em",{parentName:"p"},"not")," to traverse up the container\nparent tree until it finds a value."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"This constraint is most useful when combined with ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional"),".\nThat way, if the current container doesn't have the value, a runtime error would not occur.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"If you're a visual learner, here's a flow-chart of the resolution process with ",(0,o.kt)("code",null,"Self"),"."),(0,o.kt)("p",null,"If we were to modify our flow-chart from above, the resolution for resolving identifiers marked with ",(0,o.kt)("code",null,"Self")," would look like this:"),(0,o.kt)(a.Z,{value:'\nflowchart\n\t1("A service is requested \nfrom the container.") --\x3e 704938("Lookup the item\nin the container.")\n\t704938 --\x3e 627865{"Was it\nfound?"}\n\t627865 ---|"Yes"| 326567("Return value.")\n\t627865 ---|"No"| 415873("Throw error.")\n',mdxType:"Mermaid"})),(0,o.kt)("h2",{id:"acquire-multiple-services-with-many"},"Acquire multiple services with ",(0,o.kt)("inlineCode",{parentName:"h2"},"Many()")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"Many")," constraint is functionally equivalent to ",(0,o.kt)("inlineCode",{parentName:"p"},"Container.getMany"),".\nIt can also be combined with ",(0,o.kt)("inlineCode",{parentName:"p"},"Optional"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"SkipSelf")," (or ",(0,o.kt)("inlineCode",{parentName:"p"},"Self"),") to further constrain resolution."),(0,o.kt)("p",null,"To provide an example of this, consider the following:"),(0,o.kt)("p",null,"XXX"))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/393be207.6c4a0910.js b/assets/js/393be207.579ed0c1.js similarity index 81% rename from assets/js/393be207.6c4a0910.js rename to assets/js/393be207.579ed0c1.js index 11b979a8..dad8deab 100644 --- a/assets/js/393be207.6c4a0910.js +++ b/assets/js/393be207.579ed0c1.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[414],{9613:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(9496);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},f="mdxType",s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),m=o,d=f["".concat(i,".").concat(m)]||f[m]||s[m]||a;return r?n.createElement(d,p(p({ref:t},u),{},{components:r})):n.createElement(d,p({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,p=new Array(a);p[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[f]="string"==typeof e?e:o,p[1]=c;for(var l=2;l{r.r(t),r.d(t,{contentTitle:()=>p,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var n=r(1966),o=(r(9496),r(9613));const a={title:"Markdown page example"},p="Markdown page example",c={type:"mdx",permalink:"/typedi/markdown-page",source:"@site/src/pages/markdown-page.md",title:"Markdown page example",description:"You don't need React to write simple standalone pages.",frontMatter:{title:"Markdown page example"}},i=[],l={toc:i},u="wrapper";function f(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"markdown-page-example"},"Markdown page example"),(0,o.kt)("p",null,"You don't need React to write simple standalone pages."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[414],{9613:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(9496);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},f="mdxType",s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),m=o,d=f["".concat(i,".").concat(m)]||f[m]||s[m]||a;return r?n.createElement(d,p(p({ref:t},u),{},{components:r})):n.createElement(d,p({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,p=new Array(a);p[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[f]="string"==typeof e?e:o,p[1]=c;for(var l=2;l{r.r(t),r.d(t,{contentTitle:()=>p,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var n=r(1966),o=(r(9496),r(9613));const a={title:"Markdown page example"},p="Markdown page example",c={type:"mdx",permalink:"/markdown-page",source:"@site/src/pages/markdown-page.md",title:"Markdown page example",description:"You don't need React to write simple standalone pages.",frontMatter:{title:"Markdown page example"}},i=[],l={toc:i},u="wrapper";function f(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"markdown-page-example"},"Markdown page example"),(0,o.kt)("p",null,"You don't need React to write simple standalone pages."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3e3bd4e4.3abddf15.js b/assets/js/3e3bd4e4.3abddf15.js deleted file mode 100644 index 66c4f22e..00000000 --- a/assets/js/3e3bd4e4.3abddf15.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[603],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=i,h=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(h,a(a({ref:t},p),{},{components:n})):r.createElement(h,a({ref:t},p))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var r=n(1966),i=(n(9496),n(9613));const o={sidebar_position:1},a="Services",s={unversionedId:"guide/services/introduction",id:"guide/services/introduction",title:"Services",description:"Services are one of the core concepts of Dependency Injection.",source:"@site/docs/guide/services/introduction.md",sourceDirName:"guide/services",slug:"/guide/services/introduction",permalink:"/typedi/docs/guide/services/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Creating Containers",permalink:"/typedi/docs/guide/containers/creating-containers"},next:{title:"Multiple Services",permalink:"/typedi/docs/guide/services/multiple-services"}},c={},l=[{value:"Attaching to Containers",id:"attaching-to-containers",level:2},{value:"Finding our Service",id:"finding-our-service",level:2},{value:"Creating Instances via Factories",id:"creating-instances-via-factories",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"services"},"Services"),(0,i.kt)("p",null,"Services are one of the core concepts of Dependency Injection.\nEach service has a certain responsibility and, when each service is\nbrought together, they power the functionality of your project."),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"This page doesn't aim to be an introductory guide to Dependency Injection.")),(0,i.kt)("p",{parentName:"admonition"},"If you're new to the concept, here are some recommended learning resources:"),(0,i.kt)("ul",{parentName:"admonition"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.jamesshore.com/v2/blog/2006/dependency-injection-demystified"},(0,i.kt)("em",{parentName:"a"},'"Dependency Injection Demystified"')," by James Shore")," ",(0,i.kt)("sup",null,(0,i.kt)("a",{parentName:"li",href:"https://web.archive.org/web/20230208150338/https://www.jamesshore.com/v2/blog/2006/dependency-injection-demystified"},"(archive)"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://martinfowler.com/articles/injection.html"},(0,i.kt)("em",{parentName:"a"},'"Inversion of Control Containers and the Dependency Injection pattern"')," by Martin Fowler")," ",(0,i.kt)("sup",null,(0,i.kt)("a",{parentName:"li",href:"https://web.archive.org/web/20230406045635/https://martinfowler.com/articles/injection.html"},"(archive)"))))),(0,i.kt)("p",null,"In your typical NodeJS app, you may have the following services:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"DatabaseService"),", for handling connections to the app's database."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"WebServerService"),", which would handle the instantiation and management of your web server."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"DiagnosticsService"),", allowing for sending diagnostics to a central service.")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"To see what the above server would look like when implemented in TypeDI, check out the ",(0,i.kt)("a",{parentName:"p",href:"../../examples/nodejs-web-server/implementation"},"NodeJS Web Server")," example.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Each service manages ",(0,i.kt)("em",{parentName:"strong"},"one")," part of the application.")),(0,i.kt)("p",null,"Additionally, each service abstracts away implementation logic.\nFor example, if your application makes use of PostgreSQL now, it is most\nlikely possible that you can change the underlying database implementation within ",(0,i.kt)("inlineCode",{parentName:"p"},"DatabaseService"),"\nto support a different database, such as MySQL."),(0,i.kt)("p",null,"TypeDI lets you express services through an expressive decorator-based syntax, which allows you to:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Declare any neighbouring services a service depends on"),(0,i.kt)("li",{parentName:"ul"},"Store implementation logic in an easily-readable ES6 class format"),(0,i.kt)("li",{parentName:"ul"},"Provide a public interface for consumers of your service")),(0,i.kt)("p",null,"Let's put that into practice, while also exploring the various ways you can tweak the declaration\nof services to meet various use-cases you may require in your app."),(0,i.kt)("h2",{id:"attaching-to-containers"},"Attaching to Containers"),(0,i.kt)("p",null,"By default, services are attached to the ",(0,i.kt)("a",{parentName:"p",href:"../containers/introduction"},"default container"),".\nHowever, we can tweak this behaviour by introducing an ",(0,i.kt)("strong",{parentName:"p"},"options object")," to the ",(0,i.kt)("inlineCode",{parentName:"p"},"@Service")," decorator.\nLet's explore how our ",(0,i.kt)("a",{parentName:"p",href:"../../examples/hello-world"},"Hello World!")," example could be changed to bind the\nservice to a different container."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/log.service.ts"',title:'"src/log.service.ts"'},"import { Service, Container } from '@typed-inject/injector';\n\n// highlight-revision-start\nexport const container = Container.ofChild('my-new-container');\n// highlight-revision-end\n\n// highlight-revision-start\n@Service({ container }, [])\n// highlight-revision-end\nexport class LogService {\n public log(message: string) {\n console.log(message);\n }\n}\n")),(0,i.kt)("p",null,"What we did there was add an ",(0,i.kt)("em",{parentName:"p"},"options object")," to our service declaration. This gives TypeDI certain\ninstructions on how & why the service should be initialised. In our case, we only changed the container."),(0,i.kt)("h2",{id:"finding-our-service"},"Finding our Service"),(0,i.kt)("p",null,"As we've now moved the ",(0,i.kt)("inlineCode",{parentName:"p"},"LogService")," to a different container, the following will no longer work:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@typed-inject/injector';\nimport { LogService } from './log.service';\n\n// highlight-next-line-error\nconst logger = Container.get(LogService);\n// highlight-error-comment-start\n// ^^^^^^^^^^^^^\n// ServiceNotFoundError:\n// Service with \"LogService\" identifier was not found in the container.\n// highlight-error-comment-end\n")),(0,i.kt)("p",null,"This is because containers don't search ",(0,i.kt)("em",{parentName:"p"},"upwards"),". This is covered in ",(0,i.kt)("a",{parentName:"p",href:"../containers/introduction#container-inheritance"},"the Containers guide"),"."),(0,i.kt)("p",null,"Instead, what we have to do is use our newly-created container to find the service. Let's update our code above."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@typed-inject/injector';\n// highlight-revision-start\nimport { LogService, container } from './log.service';\n// highlight-revision-end\n\n// highlight-revision-start\nconst logger = container.get(LogService);\n// highlight-revision-end\n")),(0,i.kt)("p",null,"Perfect!"),(0,i.kt)("h2",{id:"creating-instances-via-factories"},"Creating Instances via Factories"),(0,i.kt)("p",null,"In some cases, you'll want to create a service via a function instead of have TypeDI create it for you.\nFor these cases, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," decorator allows you provide a factory function, which TypeDI will\nuse instead of the ",(0,i.kt)("inlineCode",{parentName:"p"},"new")," operator to create an instance of your service."),(0,i.kt)("p",null,"XXX"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3e3bd4e4.c1ead911.js b/assets/js/3e3bd4e4.c1ead911.js new file mode 100644 index 00000000..bc74f662 --- /dev/null +++ b/assets/js/3e3bd4e4.c1ead911.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[603],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=i,h=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(h,a(a({ref:t},p),{},{components:n})):r.createElement(h,a({ref:t},p))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var r=n(1966),i=(n(9496),n(9613));const o={sidebar_position:1},a="Services",s={unversionedId:"guide/services/introduction",id:"guide/services/introduction",title:"Services",description:"Services are one of the core concepts of Dependency Injection.",source:"@site/docs/guide/services/introduction.md",sourceDirName:"guide/services",slug:"/guide/services/introduction",permalink:"/docs/guide/services/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Creating Containers",permalink:"/docs/guide/containers/creating-containers"},next:{title:"Multiple Services",permalink:"/docs/guide/services/multiple-services"}},c={},l=[{value:"Attaching to Containers",id:"attaching-to-containers",level:2},{value:"Finding our Service",id:"finding-our-service",level:2},{value:"Creating Instances via Factories",id:"creating-instances-via-factories",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"services"},"Services"),(0,i.kt)("p",null,"Services are one of the core concepts of Dependency Injection.\nEach service has a certain responsibility and, when each service is\nbrought together, they power the functionality of your project."),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"This page doesn't aim to be an introductory guide to Dependency Injection.")),(0,i.kt)("p",{parentName:"admonition"},"If you're new to the concept, here are some recommended learning resources:"),(0,i.kt)("ul",{parentName:"admonition"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.jamesshore.com/v2/blog/2006/dependency-injection-demystified"},(0,i.kt)("em",{parentName:"a"},'"Dependency Injection Demystified"')," by James Shore")," ",(0,i.kt)("sup",null,(0,i.kt)("a",{parentName:"li",href:"https://web.archive.org/web/20230208150338/https://www.jamesshore.com/v2/blog/2006/dependency-injection-demystified"},"(archive)"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://martinfowler.com/articles/injection.html"},(0,i.kt)("em",{parentName:"a"},'"Inversion of Control Containers and the Dependency Injection pattern"')," by Martin Fowler")," ",(0,i.kt)("sup",null,(0,i.kt)("a",{parentName:"li",href:"https://web.archive.org/web/20230406045635/https://martinfowler.com/articles/injection.html"},"(archive)"))))),(0,i.kt)("p",null,"In your typical NodeJS app, you may have the following services:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"DatabaseService"),", for handling connections to the app's database."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"WebServerService"),", which would handle the instantiation and management of your web server."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"DiagnosticsService"),", allowing for sending diagnostics to a central service.")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"To see what the above server would look like when implemented in TypeDI, check out the ",(0,i.kt)("a",{parentName:"p",href:"../../examples/nodejs-web-server/implementation"},"NodeJS Web Server")," example.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Each service manages ",(0,i.kt)("em",{parentName:"strong"},"one")," part of the application.")),(0,i.kt)("p",null,"Additionally, each service abstracts away implementation logic.\nFor example, if your application makes use of PostgreSQL now, it is most\nlikely possible that you can change the underlying database implementation within ",(0,i.kt)("inlineCode",{parentName:"p"},"DatabaseService"),"\nto support a different database, such as MySQL."),(0,i.kt)("p",null,"TypeDI lets you express services through an expressive decorator-based syntax, which allows you to:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Declare any neighbouring services a service depends on"),(0,i.kt)("li",{parentName:"ul"},"Store implementation logic in an easily-readable ES6 class format"),(0,i.kt)("li",{parentName:"ul"},"Provide a public interface for consumers of your service")),(0,i.kt)("p",null,"Let's put that into practice, while also exploring the various ways you can tweak the declaration\nof services to meet various use-cases you may require in your app."),(0,i.kt)("h2",{id:"attaching-to-containers"},"Attaching to Containers"),(0,i.kt)("p",null,"By default, services are attached to the ",(0,i.kt)("a",{parentName:"p",href:"../containers/introduction"},"default container"),".\nHowever, we can tweak this behaviour by introducing an ",(0,i.kt)("strong",{parentName:"p"},"options object")," to the ",(0,i.kt)("inlineCode",{parentName:"p"},"@Service")," decorator.\nLet's explore how our ",(0,i.kt)("a",{parentName:"p",href:"../../examples/hello-world"},"Hello World!")," example could be changed to bind the\nservice to a different container."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/log.service.ts"',title:'"src/log.service.ts"'},"import { Service, Container } from '@freshgum/typedi';\n\n// highlight-revision-start\nexport const container = Container.ofChild('my-new-container');\n// highlight-revision-end\n\n// highlight-revision-start\n@Service({ container }, [])\n// highlight-revision-end\nexport class LogService {\n public log(message: string) {\n console.log(message);\n }\n}\n")),(0,i.kt)("p",null,"What we did there was add an ",(0,i.kt)("em",{parentName:"p"},"options object")," to our service declaration. This gives TypeDI certain\ninstructions on how & why the service should be initialised. In our case, we only changed the container."),(0,i.kt)("h2",{id:"finding-our-service"},"Finding our Service"),(0,i.kt)("p",null,"As we've now moved the ",(0,i.kt)("inlineCode",{parentName:"p"},"LogService")," to a different container, the following will no longer work:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@freshgum/typedi';\nimport { LogService } from './log.service';\n\n// highlight-next-line-error\nconst logger = Container.get(LogService);\n// highlight-error-comment-start\n// ^^^^^^^^^^^^^\n// ServiceNotFoundError:\n// Service with \"LogService\" identifier was not found in the container.\n// highlight-error-comment-end\n")),(0,i.kt)("p",null,"This is because containers don't search ",(0,i.kt)("em",{parentName:"p"},"upwards"),". This is covered in ",(0,i.kt)("a",{parentName:"p",href:"../containers/introduction#container-inheritance"},"the Containers guide"),"."),(0,i.kt)("p",null,"Instead, what we have to do is use our newly-created container to find the service. Let's update our code above."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@freshgum/typedi';\n// highlight-revision-start\nimport { LogService, container } from './log.service';\n// highlight-revision-end\n\n// highlight-revision-start\nconst logger = container.get(LogService);\n// highlight-revision-end\n")),(0,i.kt)("p",null,"Perfect!"),(0,i.kt)("h2",{id:"creating-instances-via-factories"},"Creating Instances via Factories"),(0,i.kt)("p",null,"In some cases, you'll want to create a service via a function instead of have TypeDI create it for you.\nFor these cases, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," decorator allows you provide a factory function, which TypeDI will\nuse instead of the ",(0,i.kt)("inlineCode",{parentName:"p"},"new")," operator to create an instance of your service."),(0,i.kt)("p",null,"XXX"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3f288906.aae31196.js b/assets/js/3f288906.aae31196.js new file mode 100644 index 00000000..d9402e1e --- /dev/null +++ b/assets/js/3f288906.aae31196.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[747],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var r=n(9496);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,a=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=c(n),d=s,g=u["".concat(l,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(g,i(i({ref:t},p),{},{components:n})):r.createElement(g,i({ref:t},p))}));function g(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var a=n.length,i=new Array(a);i[0]=d;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[u]="string"==typeof e?e:s,i[1]=o;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var r=n(1966),s=(n(9496),n(9613));const a={sidebar_position:3},i="Multiple Services",o={unversionedId:"guide/services/multiple-services",id:"guide/services/multiple-services",title:"Multiple Services",description:"In some scenarios, you may want to store multiple instances of a service",source:"@site/docs/guide/services/multiple-services.md",sourceDirName:"guide/services",slug:"/guide/services/multiple-services",permalink:"/docs/guide/services/multiple-services",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/multiple-services.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Services",permalink:"/docs/guide/services/introduction"},next:{title:"Resolution Constraints",permalink:"/docs/guide/services/resolution-constraints"}},l={},c=[],p={toc:c},u="wrapper";function m(e){let{components:t,...n}=e;return(0,s.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"multiple-services"},"Multiple Services"),(0,s.kt)("p",null,"In some scenarios, you may want to store multiple instances of a service\nin your container. Using ",(0,s.kt)("inlineCode",{parentName:"p"},"get")," wouldn't accomplish this, as subsequent\ncalls would provide the same instance."),(0,s.kt)("p",null,"However, one important feature of TypeDI is its ability to allow you\nto store multiple values under one ID. ",(0,s.kt)("strong",{parentName:"p"},"Let's explore this below with a quick example.")),(0,s.kt)("p",null,"Let's consider the example of an application which needs to store\ninformation about multiple users. Some users have different roles,\nwhich we'll also need to represent via individual services."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/user.class.ts"',title:'"src/user.class.ts"'},"export class UserService {\n public readonly role = 'user';\n constructor(public name: string) {}\n}\n")),(0,s.kt)("p",null,"Now, let's create a ",(0,s.kt)("inlineCode",{parentName:"p"},"ManagerService")," to represent managers.\nManagers should have the ability to perform administrative actions,\nso we'll add a ",(0,s.kt)("inlineCode",{parentName:"p"},"deleteComment")," method."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/manager-user.class.ts"',title:'"src/manager-user.class.ts"'},"import { User } from './user.class';\n\nexport class Manager extends User {\n public readonly role = 'manager';\n\n constructor(public name: string) {\n super(name);\n }\n\n deleteComment(commentId: string) {\n // ...\n }\n}\n")),(0,s.kt)("p",null,"To store each user, we'd also want a ",(0,s.kt)("a",{parentName:"p",href:"../tokens/introduction"},"Token")," that we can use to reference them.\nLet's do this below."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/app.ts"',title:'"src/app.ts"'},"import { Container } from '@freshgum/typedi';\nimport { User } from './user.class';\n\nexport const USER = new Token();\n\nconst joe = new User('Joe');\nconst rick = new ManagerUser('Rick');\n\nfunction addUser(value: User) {\n Container.set({ id: USER, multiple: true, value, dependencies: [] });\n}\n\naddUser(joe);\naddUser(rick);\n")),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"The advantage of this approach is that it's much easier to keep\ntrack of each service instance, as they're all stored in one\ncontainer.")),(0,s.kt)("p",null,"You'll notice that while we can ",(0,s.kt)("em",{parentName:"p"},"store")," individual users,\nwe can't currently access them. Let's fix that."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/app.ts"',title:'"src/app.ts"'},"// ...\n\nfunction getUsers() {\n // highlight-revision-start\n return Container.getMany(USER);\n // highlight-revision-end\n}\n\nconsole.log(getUsers());\n// -> [class User, class ManagerUser]\n")),(0,s.kt)("p",null,"There we go! There's a basic example of how to use multiple services in TypeDI."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3f288906.c4742133.js b/assets/js/3f288906.c4742133.js deleted file mode 100644 index 78c446df..00000000 --- a/assets/js/3f288906.c4742133.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[747],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var r=n(9496);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=c(n),d=s,g=u["".concat(l,".").concat(d)]||u[d]||m[d]||i;return n?r.createElement(g,a(a({ref:t},p),{},{components:n})):r.createElement(g,a({ref:t},p))}));function g(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var i=n.length,a=new Array(i);a[0]=d;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[u]="string"==typeof e?e:s,a[1]=o;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=n(1966),s=(n(9496),n(9613));const i={sidebar_position:3},a="Multiple Services",o={unversionedId:"guide/services/multiple-services",id:"guide/services/multiple-services",title:"Multiple Services",description:"In some scenarios, you may want to store multiple instances of a service",source:"@site/docs/guide/services/multiple-services.md",sourceDirName:"guide/services",slug:"/guide/services/multiple-services",permalink:"/typedi/docs/guide/services/multiple-services",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/multiple-services.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Services",permalink:"/typedi/docs/guide/services/introduction"},next:{title:"Resolution Constraints",permalink:"/typedi/docs/guide/services/resolution-constraints"}},l={},c=[],p={toc:c},u="wrapper";function m(e){let{components:t,...n}=e;return(0,s.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"multiple-services"},"Multiple Services"),(0,s.kt)("p",null,"In some scenarios, you may want to store multiple instances of a service\nin your container. Using ",(0,s.kt)("inlineCode",{parentName:"p"},"get")," wouldn't accomplish this, as subsequent\ncalls would provide the same instance."),(0,s.kt)("p",null,"However, one important feature of TypeDI is its ability to allow you\nto store multiple values under one ID. ",(0,s.kt)("strong",{parentName:"p"},"Let's explore this below with a quick example.")),(0,s.kt)("p",null,"Let's consider the example of an application which needs to store\ninformation about multiple users. Some users have different roles,\nwhich we'll also need to represent via individual services."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/user.class.ts"',title:'"src/user.class.ts"'},"export class UserService {\n public readonly role = 'user';\n constructor(public name: string) {}\n}\n")),(0,s.kt)("p",null,"Now, let's create a ",(0,s.kt)("inlineCode",{parentName:"p"},"ManagerService")," to represent managers.\nManagers should have the ability to perform administrative actions,\nso we'll add a ",(0,s.kt)("inlineCode",{parentName:"p"},"deleteComment")," method."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/manager-user.class.ts"',title:'"src/manager-user.class.ts"'},"import { User } from './user.class';\n\nexport class Manager extends User {\n public readonly role = 'manager';\n\n constructor(public name: string) {\n super(name);\n }\n\n deleteComment(commentId: string) {\n // ...\n }\n}\n")),(0,s.kt)("p",null,"To store each user, we'd also want a ",(0,s.kt)("a",{parentName:"p",href:"../tokens/introduction"},"Token")," that we can use to reference them.\nLet's do this below."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/app.ts"',title:'"src/app.ts"'},"import { Container } from '@typed-inject/injector';\nimport { User } from './user.class';\n\nexport const USER = new Token();\n\nconst joe = new User('Joe');\nconst rick = new ManagerUser('Rick');\n\nfunction addUser(value: User) {\n Container.set({ id: USER, multiple: true, value, dependencies: [] });\n}\n\naddUser(joe);\naddUser(rick);\n")),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"The advantage of this approach is that it's much easier to keep\ntrack of each service instance, as they're all stored in one\ncontainer.")),(0,s.kt)("p",null,"You'll notice that while we can ",(0,s.kt)("em",{parentName:"p"},"store")," individual users,\nwe can't currently access them. Let's fix that."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/app.ts"',title:'"src/app.ts"'},"// ...\n\nfunction getUsers() {\n // highlight-revision-start\n return Container.getMany(USER);\n // highlight-revision-end\n}\n\nconsole.log(getUsers());\n// -> [class User, class ManagerUser]\n")),(0,s.kt)("p",null,"There we go! There's a basic example of how to use multiple services in TypeDI."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/45395bfd.0c0531e4.js b/assets/js/45395bfd.0c0531e4.js deleted file mode 100644 index 4fc501e6..00000000 --- a/assets/js/45395bfd.0c0531e4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[856],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),m=i,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,s(s({ref:t},p),{},{components:n})):r.createElement(f,s({ref:t},p))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,s=new Array(a);s[0]=m;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[u]="string"==typeof e?e:i,s[1]=o;for(var l=2;l{n.d(t,{b:()=>i});var r=n(9751);function i(){return(0,r.Z)(...arguments)}},608:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(1966),i=n(9496),a=n(5347),s=n(1019);function o(e){let{repoPath:t,type:n,nodeID:o,...c}=e;const{siteConfig:l}=(0,s.b)(),p=t??l.customFields.github.repoPath,u=function(e,t){switch(e){case"issue":return`/issues/${t}`;case"pull-request":return`/pull/${t}`;case"discussion":return`/discussions/${t}`;default:throw new Error(`: Unexpected node type: ${e} with ID ${t}.`)}}(n,o);return i.createElement(a.Z,(0,r.Z)({to:`https://github.com/${p}${u}`},c),p,"#",o)}},1717:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var r=n(1966),i=(n(9496),n(9613)),a=n(608);const s={sidebar_position:6},o="Transient Services",c={unversionedId:"guide/services/transient-services",id:"guide/services/transient-services",title:"Transient Services",description:"Normally, when you create a service, it's cached and any further calls to Container.get",source:"@site/docs/guide/services/transient-services.mdx",sourceDirName:"guide/services",slug:"/guide/services/transient-services",permalink:"/typedi/docs/guide/services/transient-services",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/transient-services.mdx",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Singletons",permalink:"/typedi/docs/guide/services/singletons"},next:{title:"Usage in JavaScript",permalink:"/typedi/docs/guide/services/usage-in-javascript"}},l={},p=[{value:"Demo",id:"demo",level:2},{value:"Transient Services as Dependencies",id:"transient-services-as-dependencies",level:2},{value:"Transient Factories",id:"transient-factories",level:2},{value:"Performance",id:"performance",level:2}],u={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"transient-services"},"Transient Services"),(0,i.kt)("p",null,"Normally, when you create a service, it's cached and any further calls to ",(0,i.kt)("inlineCode",{parentName:"p"},"Container.get"),"\n(or when the service is used as a dependency) result in the same instance of the service."),(0,i.kt)("p",null,"In some cases, that behaviour may actually be ",(0,i.kt)("em",{parentName:"p"},"undesirable"),". For this use-case, TypeDI\nprovides ",(0,i.kt)("em",{parentName:"p"},"transient services"),", which are re-instantiated every time they're requested."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"If your service performs complicated calculations, or emits side-effects (e.g. database connections),\nyou may find that the performance of your application quickly deteriorates."),(0,i.kt)("p",{parentName:"admonition"},'To fix this, you can "hoist" the logic outside of your transient service.\nRead more about this in ',(0,i.kt)("a",{parentName:"p",href:"#performance"},"the Performance section"),".")),(0,i.kt)("h2",{id:"demo"},"Demo"),(0,i.kt)("p",null,"To demonstrate how transient services, let's create a simple example: a performance timing API.\nThe timing API should correspond with one set of marks alongside a final measurement."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/timer.service.ts"',title:'"src/timer.service.ts"'},"import { Service } from '@typed-inject/injector';\n\n@Service({ transient: true }, [ ])\nexport class TimerService {\n private name: string | null = null;\n\n start (name: string) {\n this.name = name;\n performance.mark(`${name}-start`);\n }\n\n end () {\n const endName = `${this.name}-end`;\n performance.mark(endName);\n performance.measure(this.name, `${this.name}-start`, endName);\n }\n}\n")),(0,i.kt)("p",null,"Now, we'll make use of this timing API in our page service,\na fictional service which is responsible for rendering pages."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/page.service.ts"',title:'"src/page.service.ts"'},"import { Service, HostContainer } from '@typed-inject/injector';\nimport { TimerService } from './timer.service';\n\n@Service([\n HostContainer()\n])\nexport class PageService {\n constructor (private container: ContainerInstance) { }\n\n async renderPage () {\n const timer = this.container.get(TimerService);\n timer.start('page-render');\n // Perform page rendering logic...\n timer.end();\n }\n}\n")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"The current API for getting fresh transient services isn't ideal.\n",(0,i.kt)("a",{parentName:"p",href:"./host-container"},(0,i.kt)("inlineCode",{parentName:"a"},"HostContainer")),' is an "escape hatch", and it should be avoided where possible.'),(0,i.kt)("p",{parentName:"admonition"},"The issue is being tracked and investigated in issue ",(0,i.kt)(a.Z,{type:"issue",nodeID:28,mdxType:"GitHubRefLink"}),".")),(0,i.kt)("p",null,"Now, when a page is rendered, we'll have new performance entries to upload to a central diagnostics server."),(0,i.kt)("h2",{id:"transient-services-as-dependencies"},"Transient Services as Dependencies"),(0,i.kt)("p",null,"When you use a transient service as a dependency, the same instance of the service will\nbe used over the lifetime over the consuming service. If this isn't the desired behaviour,\nyou would be better served by the ",(0,i.kt)("inlineCode",{parentName:"p"},"HostContainer()")," API, which allows you to get an instance\nof the container the service is running under."),(0,i.kt)("p",null,"Then, you can replace references to the transient service with calls to ",(0,i.kt)("inlineCode",{parentName:"p"},"Container.get"),"."),(0,i.kt)("p",null,"In the example above, we did just that. This allowed us to get a new instance of ",(0,i.kt)("inlineCode",{parentName:"p"},"TimerService"),"\nfor each page that was rendered in the app."),(0,i.kt)("h2",{id:"transient-factories"},"Transient Factories"),(0,i.kt)("p",null,"TODO"),(0,i.kt)("h2",{id:"performance"},"Performance"),(0,i.kt)("p",null,"If your transient service relies on a great number of other transient services, computes expensive\ncomputations, or creates side-effects which may affect the application, you may find that transient\nservices affect your application's performance."),(0,i.kt)("p",null,"For this reason, it's typically recommended to use static services or ",(0,i.kt)("a",{parentName:"p",href:"./singletons"},"singletons")," if\nyour workflow doesn't explicitly require services to be transient."),(0,i.kt)("p",null,"If you would still prefer transient scenarios in this case, consider ",(0,i.kt)("strong",{parentName:"p"},"hoisting")," calculations\nand side-effects out of ",(0,i.kt)("em",{parentName:"p"},"individual")," transient services, replacing them with references to a\nstatic / singleton service."),(0,i.kt)("p",null,"{/",(0,i.kt)("em",{parentName:"p"}," TODO: add hoisting example: Database and UserEntity service "),"/}"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/45395bfd.e0a879e0.js b/assets/js/45395bfd.e0a879e0.js new file mode 100644 index 00000000..f2921bb3 --- /dev/null +++ b/assets/js/45395bfd.e0a879e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[856],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),m=i,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,s(s({ref:t},p),{},{components:n})):r.createElement(f,s({ref:t},p))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,s=new Array(a);s[0]=m;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[u]="string"==typeof e?e:i,s[1]=o;for(var l=2;l{n.d(t,{b:()=>i});var r=n(9751);function i(){return(0,r.Z)(...arguments)}},608:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(1966),i=n(9496),a=n(5347),s=n(1019);function o(e){let{repoPath:t,type:n,nodeID:o,...c}=e;const{siteConfig:l}=(0,s.b)(),p=t??l.customFields.github.repoPath,u=function(e,t){switch(e){case"issue":return`/issues/${t}`;case"pull-request":return`/pull/${t}`;case"discussion":return`/discussions/${t}`;default:throw new Error(`: Unexpected node type: ${e} with ID ${t}.`)}}(n,o);return i.createElement(a.Z,(0,r.Z)({to:`https://github.com/${p}${u}`},c),p,"#",o)}},1717:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var r=n(1966),i=(n(9496),n(9613)),a=n(608);const s={sidebar_position:6},o="Transient Services",c={unversionedId:"guide/services/transient-services",id:"guide/services/transient-services",title:"Transient Services",description:"Normally, when you create a service, it's cached and any further calls to Container.get",source:"@site/docs/guide/services/transient-services.mdx",sourceDirName:"guide/services",slug:"/guide/services/transient-services",permalink:"/docs/guide/services/transient-services",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/transient-services.mdx",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Singletons",permalink:"/docs/guide/services/singletons"},next:{title:"Usage in JavaScript",permalink:"/docs/guide/services/usage-in-javascript"}},l={},p=[{value:"Demo",id:"demo",level:2},{value:"Transient Services as Dependencies",id:"transient-services-as-dependencies",level:2},{value:"Transient Factories",id:"transient-factories",level:2},{value:"Performance",id:"performance",level:2}],u={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"transient-services"},"Transient Services"),(0,i.kt)("p",null,"Normally, when you create a service, it's cached and any further calls to ",(0,i.kt)("inlineCode",{parentName:"p"},"Container.get"),"\n(or when the service is used as a dependency) result in the same instance of the service."),(0,i.kt)("p",null,"In some cases, that behaviour may actually be ",(0,i.kt)("em",{parentName:"p"},"undesirable"),". For this use-case, TypeDI\nprovides ",(0,i.kt)("em",{parentName:"p"},"transient services"),", which are re-instantiated every time they're requested."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"If your service performs complicated calculations, or emits side-effects (e.g. database connections),\nyou may find that the performance of your application quickly deteriorates."),(0,i.kt)("p",{parentName:"admonition"},'To fix this, you can "hoist" the logic outside of your transient service.\nRead more about this in ',(0,i.kt)("a",{parentName:"p",href:"#performance"},"the Performance section"),".")),(0,i.kt)("h2",{id:"demo"},"Demo"),(0,i.kt)("p",null,"To demonstrate how transient services, let's create a simple example: a performance timing API.\nThe timing API should correspond with one set of marks alongside a final measurement."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/timer.service.ts"',title:'"src/timer.service.ts"'},"import { Service } from '@freshgum/typedi';\n\n@Service({ transient: true }, [ ])\nexport class TimerService {\n private name: string | null = null;\n\n start (name: string) {\n this.name = name;\n performance.mark(`${name}-start`);\n }\n\n end () {\n const endName = `${this.name}-end`;\n performance.mark(endName);\n performance.measure(this.name, `${this.name}-start`, endName);\n }\n}\n")),(0,i.kt)("p",null,"Now, we'll make use of this timing API in our page service,\na fictional service which is responsible for rendering pages."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/page.service.ts"',title:'"src/page.service.ts"'},"import { Service, HostContainer } from '@freshgum/typedi';\nimport { TimerService } from './timer.service';\n\n@Service([\n HostContainer()\n])\nexport class PageService {\n constructor (private container: ContainerInstance) { }\n\n async renderPage () {\n const timer = this.container.get(TimerService);\n timer.start('page-render');\n // Perform page rendering logic...\n timer.end();\n }\n}\n")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"The current API for getting fresh transient services isn't ideal.\n",(0,i.kt)("a",{parentName:"p",href:"./host-container"},(0,i.kt)("inlineCode",{parentName:"a"},"HostContainer")),' is an "escape hatch", and it should be avoided where possible.'),(0,i.kt)("p",{parentName:"admonition"},"The issue is being tracked and investigated in issue ",(0,i.kt)(a.Z,{type:"issue",nodeID:28,mdxType:"GitHubRefLink"}),".")),(0,i.kt)("p",null,"Now, when a page is rendered, we'll have new performance entries to upload to a central diagnostics server."),(0,i.kt)("h2",{id:"transient-services-as-dependencies"},"Transient Services as Dependencies"),(0,i.kt)("p",null,"When you use a transient service as a dependency, the same instance of the service will\nbe used over the lifetime over the consuming service. If this isn't the desired behaviour,\nyou would be better served by the ",(0,i.kt)("inlineCode",{parentName:"p"},"HostContainer()")," API, which allows you to get an instance\nof the container the service is running under."),(0,i.kt)("p",null,"Then, you can replace references to the transient service with calls to ",(0,i.kt)("inlineCode",{parentName:"p"},"Container.get"),"."),(0,i.kt)("p",null,"In the example above, we did just that. This allowed us to get a new instance of ",(0,i.kt)("inlineCode",{parentName:"p"},"TimerService"),"\nfor each page that was rendered in the app."),(0,i.kt)("h2",{id:"transient-factories"},"Transient Factories"),(0,i.kt)("p",null,"TODO"),(0,i.kt)("h2",{id:"performance"},"Performance"),(0,i.kt)("p",null,"If your transient service relies on a great number of other transient services, computes expensive\ncomputations, or creates side-effects which may affect the application, you may find that transient\nservices affect your application's performance."),(0,i.kt)("p",null,"For this reason, it's typically recommended to use static services or ",(0,i.kt)("a",{parentName:"p",href:"./singletons"},"singletons")," if\nyour workflow doesn't explicitly require services to be transient."),(0,i.kt)("p",null,"If you would still prefer transient scenarios in this case, consider ",(0,i.kt)("strong",{parentName:"p"},"hoisting")," calculations\nand side-effects out of ",(0,i.kt)("em",{parentName:"p"},"individual")," transient services, replacing them with references to a\nstatic / singleton service."),(0,i.kt)("p",null,"{/",(0,i.kt)("em",{parentName:"p"}," TODO: add hoisting example: Database and UserEntity service "),"/}"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/520.6480633a.js b/assets/js/520.6480633a.js new file mode 100644 index 00000000..4ed8e208 --- /dev/null +++ b/assets/js/520.6480633a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[520],{7579:(e,t,i)=>{i.d(t,{z:()=>r});const r=[String,Object,Boolean,Symbol,Array,Number]},3622:(e,t,i)=>{i.d(t,{I:()=>r});const r=Symbol("EMPTY_VALUE")},5451:(e,t,i)=>{i.d(t,{G:()=>r});const r={multiple:!1,eager:!1,scope:"container",value:i(3622).I,factory:void 0}},1944:(e,t,i)=>{i.d(t,{L:()=>y,J:()=>g});class r extends Error{constructor(){super(...arguments),this.name="ContainerRegistryError"}}class s{static registerContainer(e){if(e instanceof y==!1)throw new r("Only ContainerInstance instances can be registered.");if(s.containerMap.has(e.id))throw new r("Cannot register container with same ID.");s.containerMap.set(e.id,e)}static hasContainer(e){return s.containerMap.has(e)}static getContainer(e){const t=this.containerMap.get(e);if(void 0===t)throw new r("No container is registered with the given ID.");return t}static async removeContainer(e){const t=s.containerMap.get(e.id);if(void 0===t)throw new r("No container is registered with the given ID.");s.containerMap.delete(e.id),await t.dispose()}}s.containerMap=new Map;var n=i(5146);class a extends Error{get message(){return`Service with "${this.normalizedIdentifier}" identifier was not found in the container. Register it before usage via explicitly calling the "Container.set" function or using the "@Service()" decorator.`}constructor(e){super(),this.name="ServiceNotFoundError",this.normalizedIdentifier="","string"==typeof e?this.normalizedIdentifier=e:e instanceof n.W?this.normalizedIdentifier=`Token<${e.name||"UNSET_NAME"}>`:e&&(e.name||e.prototype?.name)&&(this.normalizedIdentifier=`MaybeConstructable<${e.name??e.prototype?.name}>`)}}var o=i(2577),l=i(3622),c=i(7579),d=i(9696),h=i(5451),u=i(54);const p=new n.W("Host Container");class f{constructor(){this.disposed=!1,this.visitors=[],this.anyVisitorsPresent=!1}get notifyVisitors(){return!this.disposed&&this.anyVisitorsPresent}forEach(e){this.notifyVisitors&&this.visitors.forEach((t=>{t.disposed?this.removeVisitor(t):e(t)}))}visitChildContainer(e){this.forEach((t=>t.visitChildContainer?.(e)))}visitOrphanedContainer(e){this.forEach((t=>t.visitOrphanedContainer?.(e)))}visitNewService(e){this.forEach((t=>t.visitNewService?.(e)))}visitRetrieval(e,t){this.forEach((i=>i.visitRetrieval?.(e,t)))}addVisitor(e,t){if(this.visitors.includes(e))return!1;"visitOrphanedContainer"in e&&t!==g&&f.forwardOrphanedContainerEvents(e),this.visitors.push(e),this.anyVisitorsPresent||(this.anyVisitorsPresent=!0);const i=e.visitContainer?.(t);return!!i||(this.removeVisitor(e),!1)}removeVisitor(e){const t=this.visitors.indexOf(e);return-1!==t&&(this.visitors.splice(t,1),0===this.visitors.length&&(this.anyVisitorsPresent=!1),!0)}static forwardOrphanedContainerEvents(e){const t={get disposed(){return e.disposed},dispose(){this.disposed=!0},visitOrphanedContainer(t){this.disposed||e.visitOrphanedContainer?.(t)},visitContainer:e=>e===g};return g.acceptTreeVisitor(t)}dispose(){this.disposed||(this.disposed=!0,this.forEach((e=>e.dispose())))}}const v="throwIfDisposed",m=[p];class y{constructor(e,t){this.parent=t,this.metadataMap=new Map,this.multiServiceIds=new Map,this.disposed=!1,this.visitor=new f,this.isRetrievingPrivateToken=!1,this.id=e}has(e,t=!0){if(this[v](),m.includes(e))return!0;const i=this.getIdentifierLocation(e);return!(!t||1!==i)||0===i}getIdentifierLocation(e){return this[v](),this.metadataMap.has(e)||this.multiServiceIds.has(e)?0:this.parent&&this.parent.has(e,!0)?1:2}get(e,t){const i=this.getOrDefault(e,l.I,t);if(i===l.I)throw new a(e);return i}resolveMetadata(e,t){this[v]();const i=this.getIdentifierLocation(e);switch(i){case 2:return null;case 0:return[this.metadataMap.get(e),i];case 1:if(t){const t=this.parent?.resolveMetadata(e,!0);return t?[t[0],1]:null}return null}}getOrNull(e,t=!0){return this.getOrDefault(e,null,t)}getOrDefault(e,t,i=!0){this[v]();const r=!this.isRetrievingPrivateToken,s={recursive:i,many:!1};if(e===p)return r&&this.visitor.visitRetrieval(e,{...s,location:0}),this;const n=this.resolveMetadata(e,i);if(null===n)return r&&this.visitor.visitRetrieval(e,{...s,location:2}),t;const[a,o]=n;if(1===o){if("singleton"===a.scope)return g.getOrDefault(e,t,i);let r;r=null!=a.factory||null!=a.type?l.I:a.value;const n={...a,value:r},o=this.set(n,[...a.dependencies]);this.isRetrievingPrivateToken=!0;const c=this.getOrDefault(o,t,i);return this.isRetrievingPrivateToken=!1,this.visitor.visitRetrieval(e,{...s,location:1}),c}r&&this.visitor.visitRetrieval(e,{...s,location:o});let c=a;if("singleton"===a?.scope&&(c=g.metadataMap.get(e)),c&&!0===c.multiple)throw Error(`Cannot resolve multiple values for ${e.toString()} service!`);return c?this.getServiceValue(c):t}getMany(e,t){const i=this.getManyOrDefault(e,l.I,t);if(i===l.I)throw new a(e);return i}getManyOrNull(e,t=!0){return this.getManyOrDefault(e,null,t)}getManyOrDefault(e,t,i=!0){let r;this[v]();let s=2;if(this.multiServiceIds.has(e)?(r=this.multiServiceIds.get(e),r&&(s=0)):i&&this.parent&&this.parent.multiServiceIds.has(e)&&(r=this.parent.multiServiceIds.get(e),s=1),this.visitor.visitRetrieval(e,{recursive:i,many:!0,location:s}),!r)return t;const n="singleton"===r.scope?g:this;n.isRetrievingPrivateToken=!0;const a=r.tokens.map((e=>n.get(e,n===g?void 0:i)));return n.isRetrievingPrivateToken=!1,a}set(e,t){if(this.throwIfDisposed(),m.includes(e.id))throw Error("Virtual identifiers can not be overridden.");if("singleton"===e.scope&&g!==this)return g.set(e,t);const i=t??e?.dependencies?.map(((t,i)=>(0,u.B)(t,e,i)))??[],r={id:e.id??e.type,type:null,...h.G,...e,dependencies:i};if(this.visitor.visitNewService(r),r.multiple){const e=new n.W(`MultiMaskToken-${r.id.toString()}`),t=this.multiServiceIds.get(r.id);t?t.tokens.push(e):this.multiServiceIds.set(r.id,{scope:r.scope,tokens:[e]}),r.id=e,r.multiple=!1}return this.metadataMap.set(r.id,r),r.eager&&"transient"!==r.scope&&this.get(r.id),r.id}setValue(e,t){if("string"!=typeof e&&!(e instanceof n.W))throw Error("The ID passed to setValue must either be a string or a Token.");return this.set({id:e,value:t},[])}remove(e){if(this[v](),Array.isArray(e))e.forEach((e=>this.remove(e)));else{const t=this.metadataMap.get(e);t&&(this.disposeServiceInstance(t),this.metadataMap.delete(e))}return this}static of(e="default",t=g,i){if("default"===e)return g;let r;const n=i?.conflictDefinition??"rejectAll",a=i?.onConflict??(i?.conflictDefinition?"throw":"returnExisting"),o=i?.onFree??"returnNew";if(s.hasContainer(e)){r=s.getContainer(e);if(!("allowSameParent"===n&&r.parent===t)){if("null"===a)return null;if("throw"===a)throw Error(`A container with the specified name ("${String(e)}") already exists.`)}}else{if("null"===o)return null;if("throw"===o)throw Error(`A container with the specified name ("${String(e)}) does not already exist.`);r=new y(e,t??void 0),null===t&&g.visitor.visitOrphanedContainer(r),s.registerContainer(r)}return r}of(e,t){return y.of(e,g,t)}ofChild(e,t){this[v]();const i=y.of(e,this,t);return i&&this.visitor.visitChildContainer(i),i}reset(e={strategy:"resetValue"}){switch(this[v](),e.strategy){case"resetValue":this.metadataMap.forEach((e=>this.disposeServiceInstance(e)));break;case"resetServices":this.metadataMap.forEach((e=>this.disposeServiceInstance(e))),this.metadataMap.clear(),this.multiServiceIds.clear();break;default:throw Error("Received invalid reset strategy.")}return this}async dispose(){this[v](),this.reset({strategy:"resetServices"}),this.disposed=!0,this.visitor.dispose()}throwIfDisposed(){if(this.disposed)throw Error("Cannot use container after it has been disposed.")}getServiceValue(e){let t=l.I;const{factory:i}=e;if(e.value!==l.I)return e.value;if(!i&&!e.type)throw new o.Z(e.id);if(i){const r=e.dependencies.map((e=>({id:this.resolveTypeWrapper(e.typeWrapper),constraints:e.constraints})));if(Array.isArray(i)){const[s,n]=i;t=(this.getOrNull(s)??new s)[n](this,e.id,r)}else t=i(this,e.id,r)}if(!i&&e.type){t=new(0,e.type)(...this.getConstructorParameters(e,!0))}if("transient"!==e.scope&&t!==l.I&&(e.value=t),t===l.I)throw new o.Z(e.id);return t}getConstructorParameters({dependencies:e},t){return e.map((e=>this.resolveResolvable(e,t)))}resolveResolvable(e,t){const i=this.resolveTypeWrapper(e.typeWrapper);if(c.z.includes(i)){if(t)throw new d.m(i.name);return i}if(e.constraints){const{constraints:t}=e;let r;const s=2&t,n=4&t,o=8&t,l=1&t;if(n&&o)throw Error("SkipSelf() and Self() cannot be used at the same time.");if(n&&!this.parent)throw Error("The SkipSelf() flag was enabled, but the subject container does not have a parent.");const c=n?this.parent:this,d=!o??void 0;if(!c.has(i,d)){if(s)return null;throw new a(i)}return r=l?c.getMany(i,d):c.get(i,d),r}return this.get(i)}resolveTypeWrapper(e){const t=e.eagerType??e.lazyType?.();if(null==t)throw Error("The wrapped value could not be resolved.");return t}disposeServiceInstance(e,t=!1){this[v]();if(t||!!e.type||!!e.factory){if("function"==typeof(e?.value).dispose)try{e.value.dispose()}catch(i){}e.value=l.I}}acceptTreeVisitor(e){return this.visitor.addVisitor(e,this)}detachTreeVisitor(e){return this.visitor.removeVisitor(e)}[Symbol.iterator](){return this.metadataMap.entries()}}y.defaultContainer=new y("default");const{defaultContainer:g}=y;s.registerContainer(g)},1238:(e,t,i)=>{i.d(t,{t:()=>o});var r=i(1944),s=i(3559),n=i(5451),a=i(54);function o(e,t){return i=>{if(null==e||null==i)throw Error("The required configuration was not passed.");let o;if(Array.isArray(e)?o=e:Array.isArray(t)?o=t:"dependencies"in e&&(o=e.dependencies),!o)throw Error("The dependencies provided were not able to be resolved.");let l={id:i,type:i,...n.G,container:r.L.defaultContainer};Array.isArray(e)||(l={...l,...e});const c=o.map(((e,t)=>(0,a.B)(e,l,t))),{id:d,container:h}=l;if(h.has(d)&&!l.multiple)throw Error(`@Service() has been called twice upon ${(0,s.H)(i)}, or you have used an ID twice.`);h.set(l,c)}}},9696:(e,t,i)=>{i.d(t,{m:()=>s});var r=i(2577);class s extends r.Z{get message(){return super.message+" If your service requires built-in or unresolvable types, please use a factory."}}},2577:(e,t,i)=>{i.d(t,{Z:()=>s});var r=i(5146);class s extends Error{get message(){return`Cannot instantiate the requested value for the "${this.normalizedIdentifier}" identifier. The related metadata doesn't contain a factory or a type to instantiate.`}constructor(e){super(),this.name="CannotInstantiateValueError",this.normalizedIdentifier="","string"==typeof e?this.normalizedIdentifier=e:e instanceof r.W?this.normalizedIdentifier=`Token<${e.name||"UNSET_NAME"}>`:e&&(e.name||e.prototype?.name)&&(this.normalizedIdentifier=`MaybeConstructable<${e.name??e.prototype.name}>`)}}},7010:(e,t,i)=>{function r(){return 2}i.d(t,{Fi:()=>r})},5146:(e,t,i)=>{i.d(t,{W:()=>r});class r{constructor(e){this.name=e}}},3559:(e,t,i)=>{function r(e){return String(e.name||e)}i.d(t,{H:()=>r})},54:(e,t,i)=>{i.d(t,{B:()=>h});var r=i(7579),s=i(9696),n=i(2577),a=i(3559),o=i(5146);const l=Symbol("LAZY_REFERENCE"),c=Symbol("INJECTED_FACTORY");function d(e){let t;return e&&("string"==typeof e||e instanceof o.W||"function"==typeof e)?t={eagerType:e,lazyType:()=>e,isFactory:!1}:"object"==typeof e&&!0===e[c]?t={eagerType:null,factory:e,isFactory:!0}:e&&function(e){return!0===e[l]}(e)&&(t={eagerType:null,lazyType:()=>e.get(),isFactory:!1}),t}function h(e,t,i){let o,l;if(Array.isArray(e)){const[t,i]=e;if(null==t||null==i)throw Error("The dependency pair was not instantiated correctly.");"number"==typeof i&&(o=i),l=d(t)}else l=d(e);const{eagerType:c}=l;if(null!==c){const e=typeof l;if("function"!==e&&"object"!==e&&"string"!==e)throw new n.Z(`The identifier provided at index ${i} for service ${(0,a.H)(t.type)} is invalid.`);if(null==t.factory&&r.z.includes(c))throw new s.m(c?.name??c)}return{constraints:o,typeWrapper:l}}},8450:(e,t,i)=>{i.d(t,{Z:()=>f});var r=i(1966),s=i(9496),n=i(5924),a=i(306),o=i(4969);const l={details:"details_YVtT",isBrowser:"isBrowser_B1Ku",collapsibleContent:"collapsibleContent_mCB7"};function c(e){return!!e&&("SUMMARY"===e.tagName||c(e.parentElement))}function d(e,t){return!!e&&(e===t||d(e.parentElement,t))}function h(e){let{summary:t,children:i,...h}=e;const u=(0,a.Z)(),p=(0,s.useRef)(null),{collapsed:f,setCollapsed:v}=(0,o.u)({initialState:!h.open}),[m,y]=(0,s.useState)(h.open),g=s.isValidElement(t)?t:s.createElement("summary",null,t??"Details");return s.createElement("details",(0,r.Z)({},h,{ref:p,open:m,"data-collapsed":f,className:(0,n.Z)(l.details,u&&l.isBrowser,h.className),onMouseDown:e=>{c(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;c(t)&&d(t,p.current)&&(e.preventDefault(),f?(v(!1),y(!0)):v(!0))}}),g,s.createElement(o.z,{lazy:!1,collapsed:f,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{v(e),y(!e)}},s.createElement("div",{className:l.collapsibleContent},i)))}const u={details:"details_x2f9"},p="alert alert--info";function f(e){let{...t}=e;return s.createElement(h,(0,r.Z)({},t,{className:(0,n.Z)(p,u.details,t.className)}))}}}]); \ No newline at end of file diff --git a/assets/js/531df37a.87b69254.js b/assets/js/531df37a.87b69254.js deleted file mode 100644 index 6109f60d..00000000 --- a/assets/js/531df37a.87b69254.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[156],{9802:(e,n,t)=>{t.d(n,{Z:()=>h});var i=t(9496),a=t(5924),o=t(9262),r=t(8197);const s={admonition:"admonition_bXxR",admonitionHeading:"admonitionHeading_eOF0",admonitionIcon:"admonitionIcon_WPTW",admonitionContent:"admonitionContent_NPED"};const l={note:{infimaClassName:"secondary",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 14 16"},i.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:i.createElement(r.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 12 16"},i.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:i.createElement(r.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 12 16"},i.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:i.createElement(r.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 14 16"},i.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:i.createElement(r.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 16 16"},i.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:i.createElement(r.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},c={secondary:"note",important:"info",success:"tip",warning:"danger"};function d(e){const{mdxAdmonitionTitle:n,rest:t}=function(e){const n=i.Children.toArray(e),t=n.find((e=>i.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=i.createElement(i.Fragment,null,n.filter((e=>e!==t)));return{mdxAdmonitionTitle:t,rest:a}}(e.children);return{...e,title:e.title??n,children:t}}function h(e){const{children:n,type:t,title:r,icon:h}=d(e),p=function(e){const n=c[e]??e,t=l[n];return t||(console.warn(`No admonition config found for admonition type "${n}". Using Info as fallback.`),l.info)}(t),u=r??p.label,{iconComponent:m}=p,f=h??i.createElement(m,null);return i.createElement("div",{className:(0,a.Z)(o.k.common.admonition,o.k.common.admonitionType(e.type),"alert",`alert--${p.infimaClassName}`,s.admonition)},i.createElement("div",{className:s.admonitionHeading},i.createElement("span",{className:s.admonitionIcon},f),u),i.createElement("div",{className:s.admonitionContent},n))}},9468:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var i=t(1966),a=(t(9496),t(9613)),o=t(1362);t(9802);const r={sidebar_position:1},s="Containers",l={unversionedId:"guide/containers/introduction",id:"guide/containers/introduction",title:"Containers",description:"Containers power the majority of TypeDI. They're used to store, retrieve and instantiate services on-the-fly.",source:"@site/docs/guide/containers/introduction.mdx",sourceDirName:"guide/containers",slug:"/guide/containers/introduction",permalink:"/typedi/docs/guide/containers/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/containers/introduction.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Adding Testing",permalink:"/typedi/docs/examples/nodejs-web-server/testing"},next:{title:"Custom Containers",permalink:"/typedi/docs/guide/containers/custom-containers"}},c={},d=[{value:"Default Container",id:"default-container",level:2},{value:"Container Inheritance",id:"container-inheritance",level:2},{value:"Creating child containers",id:"creating-child-containers",level:3},{value:"Creating containers with no parent",id:"creating-containers-with-no-parent",level:3},{value:"Disposing a container",id:"disposing-a-container",level:2}],h={toc:d},p="wrapper";function u(e){let{components:n,...t}=e;return(0,a.kt)(p,(0,i.Z)({},h,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"containers"},"Containers"),(0,a.kt)("p",null,"Containers power the majority of TypeDI. They're used to store, retrieve and instantiate services on-the-fly.\nCrucially, a TypeDI-dependent application must have a container to function."),(0,a.kt)("h2",{id:"default-container"},"Default Container"),(0,a.kt)("p",null,"Thankfully, TypeDI provides one by default, which is aptly named the ",(0,a.kt)("em",{parentName:"p"},"default container"),".\nBy default, services are attached to this, and can be retrieved at any time (like we saw in our ",(0,a.kt)("a",{parentName:"p",href:"/typedi/docs/examples/hello-world"},"Hello World!")," example.)"),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"Throughout this guide, we've assumed services are bound to the default container."),(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("strong",{parentName:"p"},"This isn't always true!")," TypeDI allows you to bind services to different containers.\nRead more about this in ",(0,a.kt)("a",{parentName:"p",href:"../services/introduction#attaching-to-containers"},"the Services section"),".")),(0,a.kt)("p",null,"To get the default container, we just need to import ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," from TypeDI:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@typed-inject/injcet';\n")),(0,a.kt)("h2",{id:"container-inheritance"},"Container Inheritance"),(0,a.kt)("p",null,"One of the most powerful features of TypeDI is ",(0,a.kt)("strong",{parentName:"p"},"container inheritance.")),(0,a.kt)("p",null,"To understand how inheritance works, you first have to understand how individual containers work."),(0,a.kt)("p",null,"Each container holds an internal map of services and values. When a service is registered against\na specific container, it's added to that internal registry. Then, when the service is requested,\nthe container knows how to handle the request."),(0,a.kt)("p",null,"In most circumstances, the service knows how to handle the value itself. However, in some cases, it\nmay have to ask its ",(0,a.kt)("em",{parentName:"p"},"parent"),"."),(0,a.kt)("p",null,"By design, containers can have ",(0,a.kt)("em",{parentName:"p"},"parents"),". If a container can't find a value itself, it can defer\nthe operation to its parent. This happens ",(0,a.kt)("strong",{parentName:"p"},"recursively")," until either the value is found somewhere\nin the tree, or an error is thrown once the tree has been exhausted."),(0,a.kt)("p",null,"As a concrete example of this, let's see what happens when we register a service to the default\ncontainer, and then request the service from a newly-created child container."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container, Service } from '@typed-inject/injector';\n\n@Service([ ])\nclass MyService { }\n\nconst childContainer = Container.ofChild('my-new-container');\n\n// highlight-revision-start\nchildContainer.get(MyService);\n// highlight-revision-end\n")),(0,a.kt)("p",null,"The child container didn't know how to resolve that value, so it looked it up in its parent,\nthe defualt container, which ",(0,a.kt)("em",{parentName:"p"},"did"),". The metadata for that service was then pulled from the parent,\nwith the newly-created instance being stored in the child container and then returned to the caller."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"This highlights an important TypeDI design point: ",(0,a.kt)("strong",{parentName:"p"},"service instances are bound to the containers which\ncreated them"),". So, in the above example, even though the child container ",(0,a.kt)("em",{parentName:"p"},"resolved")," the identifier\nvia its parent (the default container), the actual instance of ",(0,a.kt)("inlineCode",{parentName:"p"},"MyService")," was then stored in the child container."),(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("strong",{parentName:"p"},"This is good!")," It gives you the flexibility to use services from other containers\nwhile also supplying them with different values.")),(0,a.kt)("details",null,(0,a.kt)("summary",null,"If you're a visual learner, here's a flow-chart of the value resolution process."),(0,a.kt)(o.Z,{value:'\nflowchart\n\t1("A service is requested \nfrom the container.") --\x3e 704938("Lookup the item\nin the container.")\n\t704938 --\x3e 627865{"Was it\nfound?"}\n\t627865 ---|"Yes"| 326567("Return value.")\n\t627865 ---|"No"| 392131{"Does container\nhave parent?"}\n\t392131 ---|"No"| 415873("Throw error.")\n\t392131 ---|"Yes"| 924841("Set container to\nparent container.")\n\t924841 --- 704938\n',mdxType:"Mermaid"})),(0,a.kt)("p",null,"Over the course of our application, we may want to make separate containers for different parts\nof the application. This will let us compartmentalise values and services under different containers,\nwith each container having a different responsibility."),(0,a.kt)("p",null,"To do this, we have multiple APIs which we will explore below."),(0,a.kt)("h3",{id:"creating-child-containers"},"Creating child containers"),(0,a.kt)("p",null,"As we explored above, all services are bound to the default container by default.\nHowever, one potentially unwanted behaviour in this API is that, if you request\nany identifiers via ",(0,a.kt)("inlineCode",{parentName:"p"},"Container.get")," (or use them as dependencies in a service and then execute that service),\nservice instances would then be cached in the default container."),(0,a.kt)("p",null,"To remedy this, we can create a ",(0,a.kt)("em",{parentName:"p"},"child container")," of the default container, like so:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@typed-inject/injector';\n\n// highlight-revision-start\nconst myNewContainer = Container.ofChild('my-new-container');\n// highlight-revision-end\n")),(0,a.kt)("p",null,"This also lets us immutably extend the default container by adding new services to\nour child container via ",(0,a.kt)("inlineCode",{parentName:"p"},"Container.set"),"."),(0,a.kt)("h3",{id:"creating-containers-with-no-parent"},"Creating containers with no parent"),(0,a.kt)("p",null,"Sometimes, you might ",(0,a.kt)("em",{parentName:"p"},"not")," want to create a container with a parent.\nIn this case, only the values explicitly set in that container (and via ",(0,a.kt)("inlineCode",{parentName:"p"},"@Service")," decorator's ",(0,a.kt)("inlineCode",{parentName:"p"},"container")," option)\nwill be available in the container."),(0,a.kt)("p",null,"Currently, the API provides the following function to achieve this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance } from '@typed-inject/injector';\n\n// highlight-revision-start\nContainerInstance.of('my-new-container-without-a-parent', null);\n// highlight-revision-end\n")),(0,a.kt)("h2",{id:"disposing-a-container"},"Disposing a container"),(0,a.kt)("p",null,"In many cases, you'll want to get rid of a container once you're finished with it.\nThis might be when you're using individual containers for worker tasks, for example."),(0,a.kt)("p",null,"In this case, you can make use of the container's ",(0,a.kt)("inlineCode",{parentName:"p"},"dispose")," method, which disposes\nof the container asynchronously."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@typed-inject/injector';\n\n// Create a new container.\nconst myNewContainer = Container.ofChild('my-new-container');\nmyNewContainer.set({ id: 'my-value', value: 'hello-world', dependencies: [ ] });\n\nmyNewContainer.dispose().then(() => console.log('disposed!'));\n")),(0,a.kt)("p",null,"Once you've disposed a container, it's essentially useless.\nYou won't be able to resolve values from it (even from its parent),\nor perform any other actions."),(0,a.kt)("p",null,"If you try to get a value from a container after you've disposed it,\nTypeDI will throw a runtime error."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"It's typically best not to dispose of the default container.\nUnless you've bound all your services to a different container,\nwithout the default container they're virtually inacessible.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/531df37a.d0a2f7b8.js b/assets/js/531df37a.d0a2f7b8.js new file mode 100644 index 00000000..a862e255 --- /dev/null +++ b/assets/js/531df37a.d0a2f7b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[156],{9802:(e,n,t)=>{t.d(n,{Z:()=>h});var i=t(9496),a=t(5924),o=t(9262),r=t(8197);const s={admonition:"admonition_bXxR",admonitionHeading:"admonitionHeading_eOF0",admonitionIcon:"admonitionIcon_WPTW",admonitionContent:"admonitionContent_NPED"};const l={note:{infimaClassName:"secondary",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 14 16"},i.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:i.createElement(r.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 12 16"},i.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:i.createElement(r.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 12 16"},i.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:i.createElement(r.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 14 16"},i.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:i.createElement(r.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 16 16"},i.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:i.createElement(r.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},c={secondary:"note",important:"info",success:"tip",warning:"danger"};function d(e){const{mdxAdmonitionTitle:n,rest:t}=function(e){const n=i.Children.toArray(e),t=n.find((e=>i.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=i.createElement(i.Fragment,null,n.filter((e=>e!==t)));return{mdxAdmonitionTitle:t,rest:a}}(e.children);return{...e,title:e.title??n,children:t}}function h(e){const{children:n,type:t,title:r,icon:h}=d(e),u=function(e){const n=c[e]??e,t=l[n];return t||(console.warn(`No admonition config found for admonition type "${n}". Using Info as fallback.`),l.info)}(t),p=r??u.label,{iconComponent:m}=u,f=h??i.createElement(m,null);return i.createElement("div",{className:(0,a.Z)(o.k.common.admonition,o.k.common.admonitionType(e.type),"alert",`alert--${u.infimaClassName}`,s.admonition)},i.createElement("div",{className:s.admonitionHeading},i.createElement("span",{className:s.admonitionIcon},f),p),i.createElement("div",{className:s.admonitionContent},n))}},9468:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var i=t(1966),a=(t(9496),t(9613)),o=t(1362);t(9802);const r={sidebar_position:1},s="Containers",l={unversionedId:"guide/containers/introduction",id:"guide/containers/introduction",title:"Containers",description:"Containers power the majority of TypeDI. They're used to store, retrieve and instantiate services on-the-fly.",source:"@site/docs/guide/containers/introduction.mdx",sourceDirName:"guide/containers",slug:"/guide/containers/introduction",permalink:"/docs/guide/containers/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/containers/introduction.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Adding Testing",permalink:"/docs/examples/nodejs-web-server/testing"},next:{title:"Custom Containers",permalink:"/docs/guide/containers/custom-containers"}},c={},d=[{value:"Default Container",id:"default-container",level:2},{value:"Container Inheritance",id:"container-inheritance",level:2},{value:"Creating child containers",id:"creating-child-containers",level:3},{value:"Creating containers with no parent",id:"creating-containers-with-no-parent",level:3},{value:"Disposing a container",id:"disposing-a-container",level:2}],h={toc:d},u="wrapper";function p(e){let{components:n,...t}=e;return(0,a.kt)(u,(0,i.Z)({},h,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"containers"},"Containers"),(0,a.kt)("p",null,"Containers power the majority of TypeDI. They're used to store, retrieve and instantiate services on-the-fly.\nCrucially, a TypeDI-dependent application must have a container to function."),(0,a.kt)("h2",{id:"default-container"},"Default Container"),(0,a.kt)("p",null,"Thankfully, TypeDI provides one by default, which is aptly named the ",(0,a.kt)("em",{parentName:"p"},"default container"),".\nBy default, services are attached to this, and can be retrieved at any time (like we saw in our ",(0,a.kt)("a",{parentName:"p",href:"/docs/examples/hello-world"},"Hello World!")," example.)"),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"Throughout this guide, we've assumed services are bound to the default container."),(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("strong",{parentName:"p"},"This isn't always true!")," TypeDI allows you to bind services to different containers.\nRead more about this in ",(0,a.kt)("a",{parentName:"p",href:"../services/introduction#attaching-to-containers"},"the Services section"),".")),(0,a.kt)("p",null,"To get the default container, we just need to import ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," from TypeDI:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@typed-inject/injcet';\n")),(0,a.kt)("h2",{id:"container-inheritance"},"Container Inheritance"),(0,a.kt)("p",null,"One of the most powerful features of TypeDI is ",(0,a.kt)("strong",{parentName:"p"},"container inheritance.")),(0,a.kt)("p",null,"To understand how inheritance works, you first have to understand how individual containers work."),(0,a.kt)("p",null,"Each container holds an internal map of services and values. When a service is registered against\na specific container, it's added to that internal registry. Then, when the service is requested,\nthe container knows how to handle the request."),(0,a.kt)("p",null,"In most circumstances, the service knows how to handle the value itself. However, in some cases, it\nmay have to ask its ",(0,a.kt)("em",{parentName:"p"},"parent"),"."),(0,a.kt)("p",null,"By design, containers can have ",(0,a.kt)("em",{parentName:"p"},"parents"),". If a container can't find a value itself, it can defer\nthe operation to its parent. This happens ",(0,a.kt)("strong",{parentName:"p"},"recursively")," until either the value is found somewhere\nin the tree, or an error is thrown once the tree has been exhausted."),(0,a.kt)("p",null,"As a concrete example of this, let's see what happens when we register a service to the default\ncontainer, and then request the service from a newly-created child container."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container, Service } from '@freshgum/typedi';\n\n@Service([ ])\nclass MyService { }\n\nconst childContainer = Container.ofChild('my-new-container');\n\n// highlight-revision-start\nchildContainer.get(MyService);\n// highlight-revision-end\n")),(0,a.kt)("p",null,"The child container didn't know how to resolve that value, so it looked it up in its parent,\nthe defualt container, which ",(0,a.kt)("em",{parentName:"p"},"did"),". The metadata for that service was then pulled from the parent,\nwith the newly-created instance being stored in the child container and then returned to the caller."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"This highlights an important TypeDI design point: ",(0,a.kt)("strong",{parentName:"p"},"service instances are bound to the containers which\ncreated them"),". So, in the above example, even though the child container ",(0,a.kt)("em",{parentName:"p"},"resolved")," the identifier\nvia its parent (the default container), the actual instance of ",(0,a.kt)("inlineCode",{parentName:"p"},"MyService")," was then stored in the child container."),(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("strong",{parentName:"p"},"This is good!")," It gives you the flexibility to use services from other containers\nwhile also supplying them with different values.")),(0,a.kt)("details",null,(0,a.kt)("summary",null,"If you're a visual learner, here's a flow-chart of the value resolution process."),(0,a.kt)(o.Z,{value:'\nflowchart\n\t1("A service is requested \nfrom the container.") --\x3e 704938("Lookup the item\nin the container.")\n\t704938 --\x3e 627865{"Was it\nfound?"}\n\t627865 ---|"Yes"| 326567("Return value.")\n\t627865 ---|"No"| 392131{"Does container\nhave parent?"}\n\t392131 ---|"No"| 415873("Throw error.")\n\t392131 ---|"Yes"| 924841("Set container to\nparent container.")\n\t924841 --- 704938\n',mdxType:"Mermaid"})),(0,a.kt)("p",null,"Over the course of our application, we may want to make separate containers for different parts\nof the application. This will let us compartmentalise values and services under different containers,\nwith each container having a different responsibility."),(0,a.kt)("p",null,"To do this, we have multiple APIs which we will explore below."),(0,a.kt)("h3",{id:"creating-child-containers"},"Creating child containers"),(0,a.kt)("p",null,"As we explored above, all services are bound to the default container by default.\nHowever, one potentially unwanted behaviour in this API is that, if you request\nany identifiers via ",(0,a.kt)("inlineCode",{parentName:"p"},"Container.get")," (or use them as dependencies in a service and then execute that service),\nservice instances would then be cached in the default container."),(0,a.kt)("p",null,"To remedy this, we can create a ",(0,a.kt)("em",{parentName:"p"},"child container")," of the default container, like so:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@freshgum/typedi';\n\n// highlight-revision-start\nconst myNewContainer = Container.ofChild('my-new-container');\n// highlight-revision-end\n")),(0,a.kt)("p",null,"This also lets us immutably extend the default container by adding new services to\nour child container via ",(0,a.kt)("inlineCode",{parentName:"p"},"Container.set"),"."),(0,a.kt)("h3",{id:"creating-containers-with-no-parent"},"Creating containers with no parent"),(0,a.kt)("p",null,"Sometimes, you might ",(0,a.kt)("em",{parentName:"p"},"not")," want to create a container with a parent.\nIn this case, only the values explicitly set in that container (and via ",(0,a.kt)("inlineCode",{parentName:"p"},"@Service")," decorator's ",(0,a.kt)("inlineCode",{parentName:"p"},"container")," option)\nwill be available in the container."),(0,a.kt)("p",null,"Currently, the API provides the following function to achieve this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance } from '@freshgum/typedi';\n\n// highlight-revision-start\nContainerInstance.of('my-new-container-without-a-parent', null);\n// highlight-revision-end\n")),(0,a.kt)("h2",{id:"disposing-a-container"},"Disposing a container"),(0,a.kt)("p",null,"In many cases, you'll want to get rid of a container once you're finished with it.\nThis might be when you're using individual containers for worker tasks, for example."),(0,a.kt)("p",null,"In this case, you can make use of the container's ",(0,a.kt)("inlineCode",{parentName:"p"},"dispose")," method, which disposes\nof the container asynchronously."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},"import { Container } from '@freshgum/typedi';\n\n// Create a new container.\nconst myNewContainer = Container.ofChild('my-new-container');\nmyNewContainer.set({ id: 'my-value', value: 'hello-world', dependencies: [ ] });\n\nmyNewContainer.dispose().then(() => console.log('disposed!'));\n")),(0,a.kt)("p",null,"Once you've disposed a container, it's essentially useless.\nYou won't be able to resolve values from it (even from its parent),\nor perform any other actions."),(0,a.kt)("p",null,"If you try to get a value from a container after you've disposed it,\nTypeDI will throw a runtime error."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"It's typically best not to dispose of the default container.\nUnless you've bound all your services to a different container,\nwithout the default container they're virtually inacessible.")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6913d2c8.3d3ea882.js b/assets/js/6913d2c8.3d3ea882.js new file mode 100644 index 00000000..8697d006 --- /dev/null +++ b/assets/js/6913d2c8.3d3ea882.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[363],{9613:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>v});var n=r(9496);function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(s[r]=e[r]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,s=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(r),m=s,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||i;return r?n.createElement(v,o(o({ref:t},p),{},{components:r})):n.createElement(v,o({ref:t},p))}));function v(e,t){var r=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var i=r.length,o=new Array(i);o[0]=m;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[u]="string"==typeof e?e:s,o[1]=a;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var n=r(1966),s=(r(9496),r(9613));const i={sidebar_position:5},o="Singletons",a={unversionedId:"guide/services/singletons",id:"guide/services/singletons",title:"Singletons",description:"Sometimes, you'll want a service to only be created once.",source:"@site/docs/guide/services/singletons.md",sourceDirName:"guide/services",slug:"/guide/services/singletons",permalink:"/docs/guide/services/singletons",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/singletons.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Resolution Constraints",permalink:"/docs/guide/services/resolution-constraints"},next:{title:"Transient Services",permalink:"/docs/guide/services/transient-services"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...r}=e;return(0,s.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"singletons"},"Singletons"),(0,s.kt)("p",null,"Sometimes, you'll want a service to only be created once.\nThis might be when it has side-effects, such as creating a web server."),(0,s.kt)("p",null,"TypeDI supports this use-case by allowing individual services to be marked as singletons.\nWhen they are, only one instance of them will ",(0,s.kt)("em",{parentName:"p"},"ever")," be created over the lifetime of the application."),(0,s.kt)("admonition",{type:"tip"},(0,s.kt)("p",{parentName:"admonition"},"Singletons are attached to the globally-available default container.\nThis means that, regardless of the container which resolves them,\nthe same value will always be returned.")),(0,s.kt)("p",null,"Singletons are created very similarly to ordinary services, with one extra configuration parameter that must be declared."),(0,s.kt)("p",null,"As an example, let's create services for an application that hosts a web server.\nWe'd only want that web server to be created once, so we'd mark it as a singleton."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/webserver.service.ts"',title:'"src/webserver.service.ts"'},"import { Service } from '@freshgum/typedi';\nimport http from 'http'; // Node's HTTP module\n\n@Service(\n {\n // highlight-revision-start\n singleton: true,\n // highlight-revision-end\n },\n []\n)\nexport class WebServerService {\n private server: http.Server;\n startServer() {\n this.server = http.createServer((request, response) => {\n response.write('Hello world!');\n response.end();\n });\n\n this.server.listen(3000);\n }\n}\n")),(0,s.kt)("p",null,"Once we've done that, we can then start the web server in our root service."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { Service } from '@freshgum/typedi';\nimport { WebServerService } from './webserver.service';\n\n@Service([WebServerService])\nexport class RootService {\n constructor(private webServer: WebServerService) {}\n\n bootstrap() {\n this.webServer.startServer();\n }\n}\n")),(0,s.kt)("p",null,"Now, any services which use the web-server as a dependency, regardless of if they\nare child containers, will always refer to that same web server instance.\nThis prevents multiple web servers from being started at once."),(0,s.kt)("admonition",{type:"tip"},(0,s.kt)("p",{parentName:"admonition"},(0,s.kt)("strong",{parentName:"p"},"Utilising singletons for run-once operations is broadly considered a good idea.")),(0,s.kt)("p",{parentName:"admonition"},"In the case of our demo application, if multiple web server instances were to start,\nyou would experience runtime errors as only one server can be hosted on a port at a time."),(0,s.kt)("p",{parentName:"admonition"},"On the contrary, TypeDI also supports ",(0,s.kt)("a",{parentName:"p",href:"/docs/guide/services/multiple-services"},"creating ",(0,s.kt)("em",{parentName:"a"},"multiple")," instances of a service"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6913d2c8.ea6cb356.js b/assets/js/6913d2c8.ea6cb356.js deleted file mode 100644 index 7556207e..00000000 --- a/assets/js/6913d2c8.ea6cb356.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[363],{9613:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(9496);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},v=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,s=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(r),v=i,m=u["".concat(c,".").concat(v)]||u[v]||d[v]||s;return r?n.createElement(m,o(o({ref:t},p),{},{components:r})):n.createElement(m,o({ref:t},p))}));function m(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var s=r.length,o=new Array(s);o[0]=v;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[u]="string"==typeof e?e:i,o[1]=a;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var n=r(1966),i=(r(9496),r(9613));const s={sidebar_position:5},o="Singletons",a={unversionedId:"guide/services/singletons",id:"guide/services/singletons",title:"Singletons",description:"Sometimes, you'll want a service to only be created once.",source:"@site/docs/guide/services/singletons.md",sourceDirName:"guide/services",slug:"/guide/services/singletons",permalink:"/typedi/docs/guide/services/singletons",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/singletons.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Resolution Constraints",permalink:"/typedi/docs/guide/services/resolution-constraints"},next:{title:"Transient Services",permalink:"/typedi/docs/guide/services/transient-services"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"singletons"},"Singletons"),(0,i.kt)("p",null,"Sometimes, you'll want a service to only be created once.\nThis might be when it has side-effects, such as creating a web server."),(0,i.kt)("p",null,"TypeDI supports this use-case by allowing individual services to be marked as singletons.\nWhen they are, only one instance of them will ",(0,i.kt)("em",{parentName:"p"},"ever")," be created over the lifetime of the application."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"Singletons are attached to the globally-available default container.\nThis means that, regardless of the container which resolves them,\nthe same value will always be returned.")),(0,i.kt)("p",null,"Singletons are created very similarly to ordinary services, with one extra configuration parameter that must be declared."),(0,i.kt)("p",null,"As an example, let's create services for an application that hosts a web server.\nWe'd only want that web server to be created once, so we'd mark it as a singleton."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/webserver.service.ts"',title:'"src/webserver.service.ts"'},"import { Service } from '@typed-inject/injector';\nimport http from 'http'; // Node's HTTP module\n\n@Service(\n {\n // highlight-revision-start\n singleton: true,\n // highlight-revision-end\n },\n []\n)\nexport class WebServerService {\n private server: http.Server;\n startServer() {\n this.server = http.createServer((request, response) => {\n response.write('Hello world!');\n response.end();\n });\n\n this.server.listen(3000);\n }\n}\n")),(0,i.kt)("p",null,"Once we've done that, we can then start the web server in our root service."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { Service } from '@typed-inject/injector';\nimport { WebServerService } from './webserver.service';\n\n@Service([WebServerService])\nexport class RootService {\n constructor(private webServer: WebServerService) {}\n\n bootstrap() {\n this.webServer.startServer();\n }\n}\n")),(0,i.kt)("p",null,"Now, any services which use the web-server as a dependency, regardless of if they\nare child containers, will always refer to that same web server instance.\nThis prevents multiple web servers from being started at once."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"Utilising singletons for run-once operations is broadly considered a good idea.")),(0,i.kt)("p",{parentName:"admonition"},"In the case of our demo application, if multiple web server instances were to start,\nyou would experience runtime errors as only one server can be hosted on a port at a time."),(0,i.kt)("p",{parentName:"admonition"},"On the contrary, TypeDI also supports ",(0,i.kt)("a",{parentName:"p",href:"/typedi/docs/guide/services/multiple-services"},"creating ",(0,i.kt)("em",{parentName:"a"},"multiple")," instances of a service"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/72140a3c.3cf290c5.js b/assets/js/72140a3c.6899ebb8.js similarity index 78% rename from assets/js/72140a3c.3cf290c5.js rename to assets/js/72140a3c.6899ebb8.js index fdb0b7fd..64481ca9 100644 --- a/assets/js/72140a3c.3cf290c5.js +++ b/assets/js/72140a3c.6899ebb8.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[962],{9613:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>f});var n=r(9496);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},m=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,p=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),u=s(r),d=i,f=u["".concat(p,".").concat(d)]||u[d]||l[d]||o;return r?n.createElement(f,a(a({ref:t},m),{},{components:r})):n.createElement(f,a({ref:t},m))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=d;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:i,a[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(1966),i=(r(9496),r(9613));const o={sidebar_class_name:"sidebar_doc_incomplete"},a="Migrating from typestack/typedi",c={unversionedId:"migration/migrating-from-upstream-typedi",id:"migration/migrating-from-upstream-typedi",title:"Migrating from typestack/typedi",description:"",source:"@site/docs/migration/migrating-from-upstream-typedi.md",sourceDirName:"migration",slug:"/migration/migrating-from-upstream-typedi",permalink:"/typedi/docs/migration/migrating-from-upstream-typedi",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/migration/migrating-from-upstream-typedi.md",tags:[],version:"current",frontMatter:{sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"React Bindings",permalink:"/typedi/docs/guide/react/introduction"},next:{title:"Contributing to TypeDI",permalink:"/typedi/docs/meta/contributing"}},p={},s=[],m={toc:s},u="wrapper";function l(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"migrating-from-typestacktypedi"},"Migrating from typestack/typedi"))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[962],{9613:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>f});var n=r(9496);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},m=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,p=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),u=s(r),d=i,f=u["".concat(p,".").concat(d)]||u[d]||l[d]||o;return r?n.createElement(f,a(a({ref:t},m),{},{components:r})):n.createElement(f,a({ref:t},m))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=d;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:i,a[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(1966),i=(r(9496),r(9613));const o={sidebar_class_name:"sidebar_doc_incomplete"},a="Migrating from typestack/typedi",c={unversionedId:"migration/migrating-from-upstream-typedi",id:"migration/migrating-from-upstream-typedi",title:"Migrating from typestack/typedi",description:"",source:"@site/docs/migration/migrating-from-upstream-typedi.md",sourceDirName:"migration",slug:"/migration/migrating-from-upstream-typedi",permalink:"/docs/migration/migrating-from-upstream-typedi",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/migration/migrating-from-upstream-typedi.md",tags:[],version:"current",frontMatter:{sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"React Bindings",permalink:"/docs/guide/react/introduction"},next:{title:"Contributing to TypeDI",permalink:"/docs/meta/contributing"}},p={},s=[],m={toc:s},u="wrapper";function l(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"migrating-from-typestacktypedi"},"Migrating from typestack/typedi"))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7281c5db.727eea00.js b/assets/js/7281c5db.d4799824.js similarity index 57% rename from assets/js/7281c5db.727eea00.js rename to assets/js/7281c5db.d4799824.js index 9f89f8b2..3b361599 100644 --- a/assets/js/7281c5db.727eea00.js +++ b/assets/js/7281c5db.d4799824.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[993],{9613:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(n),m=i,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||a;return n?r.createElement(f,o(o({ref:t},l),{},{components:n})):r.createElement(f,o({ref:t},l))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:i,o[1]=c;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var r=n(1966),i=(n(9496),n(9613));const a={sidebar_class_name:"sidebar_doc_incomplete"},o="React Bindings",c={unversionedId:"guide/react/introduction",id:"guide/react/introduction",title:"React Bindings",description:"A set of bindings have been created to simplify usage of TypeDI within React applications.",source:"@site/docs/guide/react/introduction.md",sourceDirName:"guide/react",slug:"/guide/react/introduction",permalink:"/typedi/docs/guide/react/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/react/introduction.md",tags:[],version:"current",frontMatter:{sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"Tokens",permalink:"/typedi/docs/guide/tokens/introduction"},next:{title:"Migrating from typestack/typedi",permalink:"/typedi/docs/migration/migrating-from-upstream-typedi"}},s={},u=[{value:"useService",id:"useservice",level:2}],l={toc:u},p="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(p,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"react-bindings"},"React Bindings"),(0,i.kt)("p",null,"A set of bindings have been created to simplify usage of TypeDI within React applications."),(0,i.kt)("admonition",{type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"The React hooks are currently in beta, and the API surface could\nchange at any time. They may also contain bugs."),(0,i.kt)("p",{parentName:"admonition"},"If you wish to use them in a production application, please consider locking\nthe package version used to prevent future updates from making unexpected changes.")),(0,i.kt)("p",null,"These bindings consist of the following hooks:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useService")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useServiceOrNull")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useContainer")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useTreeVisitor"))),(0,i.kt)("h2",{id:"useservice"},(0,i.kt)("inlineCode",{parentName:"h2"},"useService")),(0,i.kt)("p",null,"This hook is rather simple: it gets a service with a specific identifier from within\na specified container which, by default, is the default container instance."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[993],{9613:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(n),m=i,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||a;return n?r.createElement(f,o(o({ref:t},l),{},{components:n})):r.createElement(f,o({ref:t},l))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:i,o[1]=c;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var r=n(1966),i=(n(9496),n(9613));const a={sidebar_class_name:"sidebar_doc_incomplete"},o="React Bindings",c={unversionedId:"guide/react/introduction",id:"guide/react/introduction",title:"React Bindings",description:"A set of bindings have been created to simplify usage of TypeDI within React applications.",source:"@site/docs/guide/react/introduction.md",sourceDirName:"guide/react",slug:"/guide/react/introduction",permalink:"/docs/guide/react/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/react/introduction.md",tags:[],version:"current",frontMatter:{sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"Tokens",permalink:"/docs/guide/tokens/introduction"},next:{title:"Migrating from typestack/typedi",permalink:"/docs/migration/migrating-from-upstream-typedi"}},s={},u=[{value:"useService",id:"useservice",level:2}],l={toc:u},p="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(p,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"react-bindings"},"React Bindings"),(0,i.kt)("p",null,"A set of bindings have been created to simplify usage of TypeDI within React applications."),(0,i.kt)("admonition",{type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"The React hooks are currently in beta, and the API surface could\nchange at any time. They may also contain bugs."),(0,i.kt)("p",{parentName:"admonition"},"If you wish to use them in a production application, please consider locking\nthe package version used to prevent future updates from making unexpected changes.")),(0,i.kt)("p",null,"These bindings consist of the following hooks:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useService")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useServiceOrNull")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useContainer")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"useTreeVisitor"))),(0,i.kt)("h2",{id:"useservice"},(0,i.kt)("inlineCode",{parentName:"h2"},"useService")),(0,i.kt)("p",null,"This hook is rather simple: it gets a service with a specific identifier from within\na specified container which, by default, is the default container instance."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8167aad2.4f6a095b.js b/assets/js/8167aad2.4f6a095b.js deleted file mode 100644 index 64d88793..00000000 --- a/assets/js/8167aad2.4f6a095b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[463],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(9496);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),c=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),g=r,m=u["".concat(l,".").concat(g)]||u[g]||d[g]||i;return n?o.createElement(m,a(a({ref:t},p),{},{components:n})):o.createElement(m,a({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=g;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var o=n(1966),r=(n(9496),n(9613));const i={sidebar_position:1},a="Tokens",s={unversionedId:"guide/tokens/introduction",id:"guide/tokens/introduction",title:"Tokens",description:"In TypeDI, tokens can be used to create a reference to a static value inside the container.",source:"@site/docs/guide/tokens/introduction.md",sourceDirName:"guide/tokens",slug:"/guide/tokens/introduction",permalink:"/typedi/docs/guide/tokens/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/tokens/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Eager Services",permalink:"/typedi/docs/guide/services/eager-services"},next:{title:"React Bindings",permalink:"/typedi/docs/guide/react/introduction"}},l={},c=[{value:"Creating our Token",id:"creating-our-token",level:2},{value:"Consuming our Token",id:"consuming-our-token",level:2},{value:"Setting the value of a Token",id:"setting-the-value-of-a-token",level:2}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"tokens"},"Tokens"),(0,r.kt)("p",null,"In TypeDI, tokens can be used to create a reference to a static value inside the container.\nThey can then be injected into services as regular dependencies."),(0,r.kt)("p",null,"As an example, let's update our ",(0,r.kt)("a",{parentName:"p",href:"../../examples/hello-world"},"Hello World!")," example to\nprint the value of a token instead of a hard-coded string."),(0,r.kt)("h2",{id:"creating-our-token"},"Creating our Token"),(0,r.kt)("p",null,"First, we'll create a file which holds the token."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts",metastring:'src="app/message.token.ts"',src:'"app/message.token.ts"'},"import { Token } from '@typed-inject/injector';\n\n// highlight-revision-start\nexport const MESSAGE = new Token('The message to print to the console.');\n// highlight-revision-end\n")),(0,r.kt)("p",null,"In TypeDI, tokens are created by making new instances of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Token")," class.\nIt also accepts a type parameter, which sets the type of the value the token points to.\nFinally, a message is also accepted, which is used for debugging purposes within TypeDI."),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},'As with services, it\'s good practice to name your files according to what they contain.\nAs this file centres around exporting a token, we add a ".token.ts" suffix to the file name.')),(0,r.kt)("h2",{id:"consuming-our-token"},"Consuming our Token"),(0,r.kt)("p",null,"Let's now update our logging service to print the value of the token."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts",metastring:'src="app/log.service.ts"',src:'"app/log.service.ts"'},"import { Service } from '@typed-inject/injector';\nimport { MESSAGE } from './message.token';\n\n// highlight-revision-start\n@Service([MESSAGE])\n// highlight-revision-end\nexport class LogService {\n // highlight-revision-start\n constructor(private message: string) {}\n // highlight-revision-end\n\n public log() {\n console.log(this.message);\n }\n}\n")),(0,r.kt)("p",null,"What we've done is update our ",(0,r.kt)("inlineCode",{parentName:"p"},"LogService")," to consume the newly-created token as a dependency.\nBefore we've created our container, TypeDI doesn't know what the value of the token is."),(0,r.kt)("h2",{id:"setting-the-value-of-a-token"},"Setting the value of a Token"),(0,r.kt)("p",null,"We'll now need to tell TypeDI what the value of ",(0,r.kt)("inlineCode",{parentName:"p"},"MESSAGE")," should be before we create\nour ",(0,r.kt)("inlineCode",{parentName:"p"},"LogService"),"."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"For brevity, the ",(0,r.kt)("inlineCode",{parentName:"p"},"RootService")," service in the example is skipped here.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@typed-inject/injector';\nimport { LogService } from './log.service';\nimport { MESSAGE } from './message.token';\n\n// highlight-revision-start\nContainer.set({ id: MESSAGE, value: 'Hello World!', dependencies: [] });\n// highlight-revision-end\n\nContainer.get(LogService).log();\n")),(0,r.kt)("p",null,"If we now run our code, we'll see the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./src/main.ts\nHello World!\n")),(0,r.kt)("admonition",{title:"Did you know...",type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"In TypeDI, tokens aren't treated specially. In fact, the implementation of ",(0,r.kt)("inlineCode",{parentName:"p"},"Token")," is quite literally:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"export class Token {\n constructor(public name?: string) {}\n}\n"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8167aad2.cf954963.js b/assets/js/8167aad2.cf954963.js new file mode 100644 index 00000000..dd555a78 --- /dev/null +++ b/assets/js/8167aad2.cf954963.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[463],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(9496);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),g=o,m=u["".concat(l,".").concat(g)]||u[g]||d[g]||i;return n?r.createElement(m,a(a({ref:t},p),{},{components:n})):r.createElement(m,a({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=g;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(1966),o=(n(9496),n(9613));const i={sidebar_position:1},a="Tokens",s={unversionedId:"guide/tokens/introduction",id:"guide/tokens/introduction",title:"Tokens",description:"In TypeDI, tokens can be used to create a reference to a static value inside the container.",source:"@site/docs/guide/tokens/introduction.md",sourceDirName:"guide/tokens",slug:"/guide/tokens/introduction",permalink:"/docs/guide/tokens/introduction",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/tokens/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Eager Services",permalink:"/docs/guide/services/eager-services"},next:{title:"React Bindings",permalink:"/docs/guide/react/introduction"}},l={},c=[{value:"Creating our Token",id:"creating-our-token",level:2},{value:"Consuming our Token",id:"consuming-our-token",level:2},{value:"Setting the value of a Token",id:"setting-the-value-of-a-token",level:2}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"tokens"},"Tokens"),(0,o.kt)("p",null,"In TypeDI, tokens can be used to create a reference to a static value inside the container.\nThey can then be injected into services as regular dependencies."),(0,o.kt)("p",null,"As an example, let's update our ",(0,o.kt)("a",{parentName:"p",href:"../../examples/hello-world"},"Hello World!")," example to\nprint the value of a token instead of a hard-coded string."),(0,o.kt)("h2",{id:"creating-our-token"},"Creating our Token"),(0,o.kt)("p",null,"First, we'll create a file which holds the token."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'src="app/message.token.ts"',src:'"app/message.token.ts"'},"import { Token } from '@freshgum/typedi';\n\n// highlight-revision-start\nexport const MESSAGE = new Token('The message to print to the console.');\n// highlight-revision-end\n")),(0,o.kt)("p",null,"In TypeDI, tokens are created by making new instances of the ",(0,o.kt)("inlineCode",{parentName:"p"},"Token")," class.\nIt also accepts a type parameter, which sets the type of the value the token points to.\nFinally, a message is also accepted, which is used for debugging purposes within TypeDI."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},'As with services, it\'s good practice to name your files according to what they contain.\nAs this file centres around exporting a token, we add a ".token.ts" suffix to the file name.')),(0,o.kt)("h2",{id:"consuming-our-token"},"Consuming our Token"),(0,o.kt)("p",null,"Let's now update our logging service to print the value of the token."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'src="app/log.service.ts"',src:'"app/log.service.ts"'},"import { Service } from '@freshgum/typedi';\nimport { MESSAGE } from './message.token';\n\n// highlight-revision-start\n@Service([MESSAGE])\n// highlight-revision-end\nexport class LogService {\n // highlight-revision-start\n constructor(private message: string) {}\n // highlight-revision-end\n\n public log() {\n console.log(this.message);\n }\n}\n")),(0,o.kt)("p",null,"What we've done is update our ",(0,o.kt)("inlineCode",{parentName:"p"},"LogService")," to consume the newly-created token as a dependency.\nBefore we've created our container, TypeDI doesn't know what the value of the token is."),(0,o.kt)("h2",{id:"setting-the-value-of-a-token"},"Setting the value of a Token"),(0,o.kt)("p",null,"We'll now need to tell TypeDI what the value of ",(0,o.kt)("inlineCode",{parentName:"p"},"MESSAGE")," should be before we create\nour ",(0,o.kt)("inlineCode",{parentName:"p"},"LogService"),"."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"For brevity, the ",(0,o.kt)("inlineCode",{parentName:"p"},"RootService")," service in the example is skipped here.")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@freshgum/typedi';\nimport { LogService } from './log.service';\nimport { MESSAGE } from './message.token';\n\n// highlight-revision-start\nContainer.set({ id: MESSAGE, value: 'Hello World!', dependencies: [] });\n// highlight-revision-end\n\nContainer.get(LogService).log();\n")),(0,o.kt)("p",null,"If we now run our code, we'll see the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./src/main.ts\nHello World!\n")),(0,o.kt)("admonition",{title:"Did you know...",type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"In TypeDI, tokens aren't treated specially. In fact, the implementation of ",(0,o.kt)("inlineCode",{parentName:"p"},"Token")," is quite literally:"),(0,o.kt)("pre",{parentName:"admonition"},(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class Token {\n constructor(public name?: string) {}\n}\n"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/89113871.2ac48097.js b/assets/js/89113871.2ac48097.js deleted file mode 100644 index 5d753633..00000000 --- a/assets/js/89113871.2ac48097.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[309],{9613:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(9496);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),l=u(r),m=o,f=l["".concat(p,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},s),{},{components:r})):n.createElement(f,a({ref:t},s))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[l]="string"==typeof e?e:o,a[1]=c;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=r(1966),o=(r(9496),r(9613));const i={sidebar_position:1},a="Contributing to TypeDI",c={unversionedId:"meta/contributing",id:"meta/contributing",title:"Contributing to TypeDI",description:"",source:"@site/docs/meta/contributing.md",sourceDirName:"meta",slug:"/meta/contributing",permalink:"/typedi/docs/meta/contributing",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/meta/contributing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Migrating from typestack/typedi",permalink:"/typedi/docs/migration/migrating-from-upstream-typedi"},next:{title:"Code of Conduct",permalink:"/typedi/docs/meta/code-of-conduct"}},p={},u=[],s={toc:u},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"contributing-to-typedi"},"Contributing to TypeDI"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/89113871.c9befc60.js b/assets/js/89113871.c9befc60.js new file mode 100644 index 00000000..541b0092 --- /dev/null +++ b/assets/js/89113871.c9befc60.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[309],{9613:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(9496);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),p=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(u.Provider,{value:t},e.children)},l="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),l=p(r),d=o,f=l["".concat(u,".").concat(d)]||l[d]||m[d]||i;return r?n.createElement(f,a(a({ref:t},s),{},{components:r})):n.createElement(f,a({ref:t},s))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[l]="string"==typeof e?e:o,a[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(1966),o=(r(9496),r(9613));const i={sidebar_position:1},a="Contributing to TypeDI",c={unversionedId:"meta/contributing",id:"meta/contributing",title:"Contributing to TypeDI",description:"",source:"@site/docs/meta/contributing.md",sourceDirName:"meta",slug:"/meta/contributing",permalink:"/docs/meta/contributing",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/meta/contributing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Migrating from typestack/typedi",permalink:"/docs/migration/migrating-from-upstream-typedi"},next:{title:"Code of Conduct",permalink:"/docs/meta/code-of-conduct"}},u={},p=[],s={toc:p},l="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"contributing-to-typedi"},"Contributing to TypeDI"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.21b271de.js b/assets/js/935f2afb.21b271de.js deleted file mode 100644 index a79da2ac..00000000 --- a/assets/js/935f2afb.21b271de.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting Started","href":"/typedi/docs/getting-started","docId":"getting-started"},{"type":"category","label":"Examples","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Hello World!","href":"/typedi/docs/examples/hello-world","docId":"examples/hello-world"},{"type":"category","label":"NodeJS Web Server","collapsible":true,"collapsed":true,"className":"sidebar_doc_incomplete","items":[{"type":"link","label":"Stopping Our App","href":"/typedi/docs/examples/nodejs-web-server/application-disposal","className":"sidebar_doc_incomplete","docId":"examples/nodejs-web-server/application-disposal"},{"type":"link","label":"Adding Testing","href":"/typedi/docs/examples/nodejs-web-server/testing","className":"sidebar_doc_incomplete","docId":"examples/nodejs-web-server/testing"}],"href":"/typedi/docs/examples/nodejs-web-server/implementation"}]},{"type":"category","label":"Learning TypeDI","collapsible":false,"collapsed":false,"items":[{"type":"category","label":"Containers","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Custom Containers","href":"/typedi/docs/guide/containers/custom-containers","docId":"guide/containers/custom-containers"},{"type":"link","label":"Creating Containers","href":"/typedi/docs/guide/containers/creating-containers","docId":"guide/containers/creating-containers"}],"href":"/typedi/docs/guide/containers/introduction"},{"type":"category","label":"Services","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Multiple Services","href":"/typedi/docs/guide/services/multiple-services","docId":"guide/services/multiple-services"},{"type":"link","label":"Resolution Constraints","href":"/typedi/docs/guide/services/resolution-constraints","docId":"guide/services/resolution-constraints"},{"type":"link","label":"Singletons","href":"/typedi/docs/guide/services/singletons","docId":"guide/services/singletons"},{"type":"link","label":"Transient Services","href":"/typedi/docs/guide/services/transient-services","docId":"guide/services/transient-services"},{"type":"link","label":"Usage in JavaScript","href":"/typedi/docs/guide/services/usage-in-javascript","docId":"guide/services/usage-in-javascript"},{"type":"link","label":"HostContainer","href":"/typedi/docs/guide/services/host-container","docId":"guide/services/host-container"},{"type":"link","label":"Eager Services","href":"/typedi/docs/guide/services/eager-services","docId":"guide/services/eager-services"}],"href":"/typedi/docs/guide/services/introduction"},{"type":"link","label":"Tokens","href":"/typedi/docs/guide/tokens/introduction","docId":"guide/tokens/introduction"},{"type":"link","label":"React Bindings","href":"/typedi/docs/guide/react/introduction","docId":"guide/react/introduction"}]},{"type":"category","label":"Migration","collapsible":false,"collapsed":false,"className":"sidebar_doc_incomplete","items":[{"type":"link","label":"Migrating from typestack/typedi","href":"/typedi/docs/migration/migrating-from-upstream-typedi","className":"sidebar_doc_incomplete","docId":"migration/migrating-from-upstream-typedi"}]},{"type":"category","label":"Meta","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Contributing to TypeDI","href":"/typedi/docs/meta/contributing","docId":"meta/contributing"},{"type":"link","label":"Code of Conduct","href":"/typedi/docs/meta/code-of-conduct","docId":"meta/code-of-conduct"},{"type":"link","label":"License","href":"/typedi/docs/meta/license","docId":"meta/license"}]}]},"docs":{"examples/hello-world":{"id":"examples/hello-world","title":"Hello World!","description":"The most basic application you can write is one which logs \\"Hello World!\\" and then exits.","sidebar":"tutorialSidebar"},"examples/nodejs-web-server/application-disposal":{"id":"examples/nodejs-web-server/application-disposal","title":"Stopping Our App","description":"Our WebServerService is pretty smart. It creates a server for us on-demand,","sidebar":"tutorialSidebar"},"examples/nodejs-web-server/implementation":{"id":"examples/nodejs-web-server/implementation","title":"NodeJS Web Server","description":"In the Services section, we talk about an implementation","sidebar":"tutorialSidebar"},"examples/nodejs-web-server/testing":{"id":"examples/nodejs-web-server/testing","title":"Adding Testing","description":"One primary advantage of using TypeDI, and Dependency Injection","sidebar":"tutorialSidebar"},"getting-started":{"id":"getting-started","title":"Getting Started","description":"Welcome to the TypeDI documentation! To get started, you\'ll need to ensure you have a working","sidebar":"tutorialSidebar"},"guide/containers/creating-containers":{"id":"guide/containers/creating-containers","title":"Creating Containers","description":"TypeDI maintains a global container registry, which is a shared","sidebar":"tutorialSidebar"},"guide/containers/custom-containers":{"id":"guide/containers/custom-containers","title":"Custom Containers","description":"In some scenarios, you may wish to change how containers work.","sidebar":"tutorialSidebar"},"guide/containers/introduction":{"id":"guide/containers/introduction","title":"Containers","description":"Containers power the majority of TypeDI. They\'re used to store, retrieve and instantiate services on-the-fly.","sidebar":"tutorialSidebar"},"guide/react/introduction":{"id":"guide/react/introduction","title":"React Bindings","description":"A set of bindings have been created to simplify usage of TypeDI within React applications.","sidebar":"tutorialSidebar"},"guide/services/eager-services":{"id":"guide/services/eager-services","title":"Eager Services","description":"Ordinarily, services aren\'t created until either:","sidebar":"tutorialSidebar"},"guide/services/host-container":{"id":"guide/services/host-container","title":"HostContainer","description":"Sometimes, you\'ll encounter a situation within your app that","sidebar":"tutorialSidebar"},"guide/services/introduction":{"id":"guide/services/introduction","title":"Services","description":"Services are one of the core concepts of Dependency Injection.","sidebar":"tutorialSidebar"},"guide/services/multiple-services":{"id":"guide/services/multiple-services","title":"Multiple Services","description":"In some scenarios, you may want to store multiple instances of a service","sidebar":"tutorialSidebar"},"guide/services/resolution-constraints":{"id":"guide/services/resolution-constraints","title":"Resolution Constraints","description":"Many times, you\'ll want a service to rely on a dependency, but there\'s always","sidebar":"tutorialSidebar"},"guide/services/singletons":{"id":"guide/services/singletons","title":"Singletons","description":"Sometimes, you\'ll want a service to only be created once.","sidebar":"tutorialSidebar"},"guide/services/transient-services":{"id":"guide/services/transient-services","title":"Transient Services","description":"Normally, when you create a service, it\'s cached and any further calls to Container.get","sidebar":"tutorialSidebar"},"guide/services/usage-in-javascript":{"id":"guide/services/usage-in-javascript","title":"Usage in JavaScript","description":"TypeDI is primarily developed for use in TypeScript.","sidebar":"tutorialSidebar"},"guide/tokens/introduction":{"id":"guide/tokens/introduction","title":"Tokens","description":"In TypeDI, tokens can be used to create a reference to a static value inside the container.","sidebar":"tutorialSidebar"},"meta/code-of-conduct":{"id":"meta/code-of-conduct","title":"Code of Conduct","description":"Our Pledge","sidebar":"tutorialSidebar"},"meta/contributing":{"id":"meta/contributing","title":"Contributing to TypeDI","description":"","sidebar":"tutorialSidebar"},"meta/license":{"id":"meta/license","title":"License","description":"","sidebar":"tutorialSidebar"},"migration/migrating-from-upstream-typedi":{"id":"migration/migrating-from-upstream-typedi","title":"Migrating from typestack/typedi","description":"","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.b89b4ba2.js b/assets/js/935f2afb.b89b4ba2.js new file mode 100644 index 00000000..278806ff --- /dev/null +++ b/assets/js/935f2afb.b89b4ba2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting Started","href":"/docs/getting-started","docId":"getting-started"},{"type":"category","label":"Examples","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Hello World!","href":"/docs/examples/hello-world","docId":"examples/hello-world"},{"type":"category","label":"NodeJS Web Server","collapsible":true,"collapsed":true,"className":"sidebar_doc_incomplete","items":[{"type":"link","label":"Stopping Our App","href":"/docs/examples/nodejs-web-server/application-disposal","className":"sidebar_doc_incomplete","docId":"examples/nodejs-web-server/application-disposal"},{"type":"link","label":"Adding Testing","href":"/docs/examples/nodejs-web-server/testing","className":"sidebar_doc_incomplete","docId":"examples/nodejs-web-server/testing"}],"href":"/docs/examples/nodejs-web-server/implementation"}]},{"type":"category","label":"Learning TypeDI","collapsible":false,"collapsed":false,"items":[{"type":"category","label":"Containers","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Custom Containers","href":"/docs/guide/containers/custom-containers","docId":"guide/containers/custom-containers"},{"type":"link","label":"Creating Containers","href":"/docs/guide/containers/creating-containers","docId":"guide/containers/creating-containers"}],"href":"/docs/guide/containers/introduction"},{"type":"category","label":"Services","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Multiple Services","href":"/docs/guide/services/multiple-services","docId":"guide/services/multiple-services"},{"type":"link","label":"Resolution Constraints","href":"/docs/guide/services/resolution-constraints","docId":"guide/services/resolution-constraints"},{"type":"link","label":"Singletons","href":"/docs/guide/services/singletons","docId":"guide/services/singletons"},{"type":"link","label":"Transient Services","href":"/docs/guide/services/transient-services","docId":"guide/services/transient-services"},{"type":"link","label":"Usage in JavaScript","href":"/docs/guide/services/usage-in-javascript","docId":"guide/services/usage-in-javascript"},{"type":"link","label":"HostContainer","href":"/docs/guide/services/host-container","docId":"guide/services/host-container"},{"type":"link","label":"Eager Services","href":"/docs/guide/services/eager-services","docId":"guide/services/eager-services"}],"href":"/docs/guide/services/introduction"},{"type":"link","label":"Tokens","href":"/docs/guide/tokens/introduction","docId":"guide/tokens/introduction"},{"type":"link","label":"React Bindings","href":"/docs/guide/react/introduction","docId":"guide/react/introduction"}]},{"type":"category","label":"Migration","collapsible":false,"collapsed":false,"className":"sidebar_doc_incomplete","items":[{"type":"link","label":"Migrating from typestack/typedi","href":"/docs/migration/migrating-from-upstream-typedi","className":"sidebar_doc_incomplete","docId":"migration/migrating-from-upstream-typedi"}]},{"type":"category","label":"Meta","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Contributing to TypeDI","href":"/docs/meta/contributing","docId":"meta/contributing"},{"type":"link","label":"Code of Conduct","href":"/docs/meta/code-of-conduct","docId":"meta/code-of-conduct"},{"type":"link","label":"License","href":"/docs/meta/license","docId":"meta/license"}]}]},"docs":{"examples/hello-world":{"id":"examples/hello-world","title":"Hello World!","description":"The most basic application you can write is one which logs \\"Hello World!\\" and then exits.","sidebar":"tutorialSidebar"},"examples/nodejs-web-server/application-disposal":{"id":"examples/nodejs-web-server/application-disposal","title":"Stopping Our App","description":"Our WebServerService is pretty smart. It creates a server for us on-demand,","sidebar":"tutorialSidebar"},"examples/nodejs-web-server/implementation":{"id":"examples/nodejs-web-server/implementation","title":"NodeJS Web Server","description":"In the Services section, we talk about an implementation","sidebar":"tutorialSidebar"},"examples/nodejs-web-server/testing":{"id":"examples/nodejs-web-server/testing","title":"Adding Testing","description":"One primary advantage of using TypeDI, and Dependency Injection","sidebar":"tutorialSidebar"},"getting-started":{"id":"getting-started","title":"Getting Started","description":"Welcome to the TypeDI documentation! To get started, you\'ll need to ensure you have a working","sidebar":"tutorialSidebar"},"guide/containers/creating-containers":{"id":"guide/containers/creating-containers","title":"Creating Containers","description":"TypeDI maintains a global container registry, which is a shared","sidebar":"tutorialSidebar"},"guide/containers/custom-containers":{"id":"guide/containers/custom-containers","title":"Custom Containers","description":"In some scenarios, you may wish to change how containers work.","sidebar":"tutorialSidebar"},"guide/containers/introduction":{"id":"guide/containers/introduction","title":"Containers","description":"Containers power the majority of TypeDI. They\'re used to store, retrieve and instantiate services on-the-fly.","sidebar":"tutorialSidebar"},"guide/react/introduction":{"id":"guide/react/introduction","title":"React Bindings","description":"A set of bindings have been created to simplify usage of TypeDI within React applications.","sidebar":"tutorialSidebar"},"guide/services/eager-services":{"id":"guide/services/eager-services","title":"Eager Services","description":"Ordinarily, services aren\'t created until either:","sidebar":"tutorialSidebar"},"guide/services/host-container":{"id":"guide/services/host-container","title":"HostContainer","description":"Sometimes, you\'ll encounter a situation within your app that","sidebar":"tutorialSidebar"},"guide/services/introduction":{"id":"guide/services/introduction","title":"Services","description":"Services are one of the core concepts of Dependency Injection.","sidebar":"tutorialSidebar"},"guide/services/multiple-services":{"id":"guide/services/multiple-services","title":"Multiple Services","description":"In some scenarios, you may want to store multiple instances of a service","sidebar":"tutorialSidebar"},"guide/services/resolution-constraints":{"id":"guide/services/resolution-constraints","title":"Resolution Constraints","description":"Many times, you\'ll want a service to rely on a dependency, but there\'s always","sidebar":"tutorialSidebar"},"guide/services/singletons":{"id":"guide/services/singletons","title":"Singletons","description":"Sometimes, you\'ll want a service to only be created once.","sidebar":"tutorialSidebar"},"guide/services/transient-services":{"id":"guide/services/transient-services","title":"Transient Services","description":"Normally, when you create a service, it\'s cached and any further calls to Container.get","sidebar":"tutorialSidebar"},"guide/services/usage-in-javascript":{"id":"guide/services/usage-in-javascript","title":"Usage in JavaScript","description":"TypeDI is primarily developed for use in TypeScript.","sidebar":"tutorialSidebar"},"guide/tokens/introduction":{"id":"guide/tokens/introduction","title":"Tokens","description":"In TypeDI, tokens can be used to create a reference to a static value inside the container.","sidebar":"tutorialSidebar"},"meta/code-of-conduct":{"id":"meta/code-of-conduct","title":"Code of Conduct","description":"Our Pledge","sidebar":"tutorialSidebar"},"meta/contributing":{"id":"meta/contributing","title":"Contributing to TypeDI","description":"","sidebar":"tutorialSidebar"},"meta/license":{"id":"meta/license","title":"License","description":"","sidebar":"tutorialSidebar"},"migration/migrating-from-upstream-typedi":{"id":"migration/migrating-from-upstream-typedi","title":"Migrating from typestack/typedi","description":"","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/9d628f83.1eb64dad.js b/assets/js/9d628f83.1eb64dad.js new file mode 100644 index 00000000..7efb5f8a --- /dev/null +++ b/assets/js/9d628f83.1eb64dad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[909],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var r=n(9496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,g=u["".concat(c,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(g,o(o({ref:t},p),{},{components:n})):r.createElement(g,o({ref:t},p))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(1966),a=(n(9496),n(9613));const i={sidebar_position:8},o="Eager Services",s={unversionedId:"guide/services/eager-services",id:"guide/services/eager-services",title:"Eager Services",description:"Ordinarily, services aren't created until either:",source:"@site/docs/guide/services/eager-services.md",sourceDirName:"guide/services",slug:"/guide/services/eager-services",permalink:"/docs/guide/services/eager-services",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/eager-services.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"HostContainer",permalink:"/docs/guide/services/host-container"},next:{title:"Tokens",permalink:"/docs/guide/tokens/introduction"}},c={},l=[{value:"Example",id:"example",level:2},{value:"The Dangers of eager: true",id:"the-dangers-of-eager-true",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"eager-services"},"Eager Services"),(0,a.kt)("p",null,"Ordinarily, services aren't created until either:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"They're explicitly called via ",(0,a.kt)("inlineCode",{parentName:"li"},"Container.get"),", or..."),(0,a.kt)("li",{parentName:"ul"},"A service which ",(0,a.kt)("em",{parentName:"li"},"is")," called via ",(0,a.kt)("inlineCode",{parentName:"li"},"Container.get")," uses the service as a dependency.")),(0,a.kt)("p",null,"Therefore, if you need a way to start a service immediately, TypeDI provides a concept called Eager Services."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"Eager Services create fragile application code, and should only be used in a few limited scenarios.\nIf you think you need this feature, consider its application carefully and use it very frugally."),(0,a.kt)("p",{parentName:"admonition"},"In future, eager services will not be initialised by default without an explicit call to ",(0,a.kt)("inlineCode",{parentName:"p"},"enableEagerLoading")," (see ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/freshgum-bubbles/typedi/pull/17"},"#17"),")."),(0,a.kt)("p",{parentName:"admonition"},"For more information on why eager services are discouraged, ",(0,a.kt)("a",{parentName:"p",href:"#the-dangers-of-eager-true"},"see the section below on its dangers"),".")),(0,a.kt)("h2",{id:"example"},"Example"),(0,a.kt)("p",null,"To create a service which is immediately run upon declaration, we can do the following:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/log.service.ts"',title:'"src/log.service.ts"'},"import { Service } from '@freshgum/typedi';\n\n@Service({ eager: true }, [])\nexport class LogService {\n constructor() {\n this.log('LogService is ready!');\n }\n\n public log(message: string) {\n console.log(message);\n }\n}\n")),(0,a.kt)("p",null,"Then, once ",(0,a.kt)("inlineCode",{parentName:"p"},"LogService")," is imported, its constructor will immediately run and log the message to the console."),(0,a.kt)("h2",{id:"the-dangers-of-eager-true"},"The Dangers of ",(0,a.kt)("inlineCode",{parentName:"h2"},"eager: true")),(0,a.kt)("p",null,"If you declare an eager service, the service won't be run until it's been imported by another file.\nTherefore, if you forget to import your eager ",(0,a.kt)("inlineCode",{parentName:"p"},"DatabaseService"),", the connection to the database won't\nbe initialised early on in the application flow."),(0,a.kt)("p",null,"Another pain-point of eager services is testability: by making side-effects run on import, we\ncreate a dangerous precedent for the API, and overall make it much harder to test."),(0,a.kt)("p",null,"Consider the following (simplified) example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/database.service.ts"',title:'"src/database.service.ts"'},"import { Service } from '@freshgum/typedi';\n\n@Service({ eager: true }, [])\nexport class DatabaseService {\n constructor() {\n this.connect();\n }\n\n private connection: Connection;\n\n private async connect() {\n // Connect to the database here...\n }\n\n public async getValue(name: string): string {\n return this.connection.getValue(name);\n }\n}\n")),(0,a.kt)("p",null,"If we're looking to test our application and replace ",(0,a.kt)("inlineCode",{parentName:"p"},"DatabaseService")," with something else,\nhow would we import it to get the ID to replace?"),(0,a.kt)("p",null,"Normally, to stub the database connection, you would do something like this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="spec/app.service.ts"',title:'"spec/app.service.ts"'},"import { Service } from '@freshgum/typedi';\nimport { DatabaseService } from '../src/database.service.ts'; // Oops!\n\n@Service({ id: DatabaseService }, [])\nexport class FakeDatabaseService implements DatabaseService {\n private map = new Map();\n\n private async connect() {}\n\n public async getValue(name: string): string {\n return this.map.get(name);\n }\n}\n\n// Test our app...\n")),(0,a.kt)("p",null,"Do you see the issue? We've imported ",(0,a.kt)("inlineCode",{parentName:"p"},"DatabaseService")," to get its ID (to replace with a stub),\nbut by doing that, we've created a connection to the database!\nThis means that, currently, we can't test the application without also creating a wasted database connection."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"Instead of using eager services, consider creating a root service which runs side effects\nsuch as database initialisation before the rest of the environment is loaded.\nThis does the same thing without the above disadvantages.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9d628f83.894c32a1.js b/assets/js/9d628f83.894c32a1.js deleted file mode 100644 index dde85838..00000000 --- a/assets/js/9d628f83.894c32a1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[909],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var r=n(9496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,g=u["".concat(c,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(g,o(o({ref:t},p),{},{components:n})):r.createElement(g,o({ref:t},p))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(1966),a=(n(9496),n(9613));const i={sidebar_position:8},o="Eager Services",s={unversionedId:"guide/services/eager-services",id:"guide/services/eager-services",title:"Eager Services",description:"Ordinarily, services aren't created until either:",source:"@site/docs/guide/services/eager-services.md",sourceDirName:"guide/services",slug:"/guide/services/eager-services",permalink:"/typedi/docs/guide/services/eager-services",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/eager-services.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"HostContainer",permalink:"/typedi/docs/guide/services/host-container"},next:{title:"Tokens",permalink:"/typedi/docs/guide/tokens/introduction"}},c={},l=[{value:"Example",id:"example",level:2},{value:"The Dangers of eager: true",id:"the-dangers-of-eager-true",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"eager-services"},"Eager Services"),(0,a.kt)("p",null,"Ordinarily, services aren't created until either:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"They're explicitly called via ",(0,a.kt)("inlineCode",{parentName:"li"},"Container.get"),", or..."),(0,a.kt)("li",{parentName:"ul"},"A service which ",(0,a.kt)("em",{parentName:"li"},"is")," called via ",(0,a.kt)("inlineCode",{parentName:"li"},"Container.get")," uses the service as a dependency.")),(0,a.kt)("p",null,"Therefore, if you need a way to start a service immediately, TypeDI provides a concept called Eager Services."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"Eager Services create fragile application code, and should only be used in a few limited scenarios.\nIf you think you need this feature, consider its application carefully and use it very frugally."),(0,a.kt)("p",{parentName:"admonition"},"In future, eager services will not be initialised by default without an explicit call to ",(0,a.kt)("inlineCode",{parentName:"p"},"enableEagerLoading")," (see ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/freshgum-bubbles/typedi/pull/17"},"#17"),")."),(0,a.kt)("p",{parentName:"admonition"},"For more information on why eager services are discouraged, ",(0,a.kt)("a",{parentName:"p",href:"#the-dangers-of-eager-true"},"see the section below on its dangers"),".")),(0,a.kt)("h2",{id:"example"},"Example"),(0,a.kt)("p",null,"To create a service which is immediately run upon declaration, we can do the following:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/log.service.ts"',title:'"src/log.service.ts"'},"import { Service } from '@typed-inject/injector';\n\n@Service({ eager: true }, [])\nexport class LogService {\n constructor() {\n this.log('LogService is ready!');\n }\n\n public log(message: string) {\n console.log(message);\n }\n}\n")),(0,a.kt)("p",null,"Then, once ",(0,a.kt)("inlineCode",{parentName:"p"},"LogService")," is imported, its constructor will immediately run and log the message to the console."),(0,a.kt)("h2",{id:"the-dangers-of-eager-true"},"The Dangers of ",(0,a.kt)("inlineCode",{parentName:"h2"},"eager: true")),(0,a.kt)("p",null,"If you declare an eager service, the service won't be run until it's been imported by another file.\nTherefore, if you forget to import your eager ",(0,a.kt)("inlineCode",{parentName:"p"},"DatabaseService"),", the connection to the database won't\nbe initialised early on in the application flow."),(0,a.kt)("p",null,"Another pain-point of eager services is testability: by making side-effects run on import, we\ncreate a dangerous precedent for the API, and overall make it much harder to test."),(0,a.kt)("p",null,"Consider the following (simplified) example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/database.service.ts"',title:'"src/database.service.ts"'},"import { Service } from '@typed-inject/injector';\n\n@Service({ eager: true }, [])\nexport class DatabaseService {\n constructor() {\n this.connect();\n }\n\n private connection: Connection;\n\n private async connect() {\n // Connect to the database here...\n }\n\n public async getValue(name: string): string {\n return this.connection.getValue(name);\n }\n}\n")),(0,a.kt)("p",null,"If we're looking to test our application and replace ",(0,a.kt)("inlineCode",{parentName:"p"},"DatabaseService")," with something else,\nhow would we import it to get the ID to replace?"),(0,a.kt)("p",null,"Normally, to stub the database connection, you would do something like this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="spec/app.service.ts"',title:'"spec/app.service.ts"'},"import { Service } from '@typed-inject/injector';\nimport { DatabaseService } from '../src/database.service.ts'; // Oops!\n\n@Service({ id: DatabaseService }, [])\nexport class FakeDatabaseService implements DatabaseService {\n private map = new Map();\n\n private async connect() {}\n\n public async getValue(name: string): string {\n return this.map.get(name);\n }\n}\n\n// Test our app...\n")),(0,a.kt)("p",null,"Do you see the issue? We've imported ",(0,a.kt)("inlineCode",{parentName:"p"},"DatabaseService")," to get its ID (to replace with a stub),\nbut by doing that, we've created a connection to the database!\nThis means that, currently, we can't test the application without also creating a wasted database connection."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"Instead of using eager services, consider creating a root service which runs side effects\nsuch as database initialisation before the rest of the environment is loaded.\nThis does the same thing without the above disadvantages.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a8b2a833.0897f0d6.js b/assets/js/a8b2a833.0897f0d6.js new file mode 100644 index 00000000..b2231412 --- /dev/null +++ b/assets/js/a8b2a833.0897f0d6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[120],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var r=n(9496);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),m=o,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(h,a(a({ref:t},p),{},{components:n})):r.createElement(h,a({ref:t},p))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(1966),o=(n(9496),n(9613));const i={sidebar_position:1},a="Hello World!",l={unversionedId:"examples/hello-world",id:"examples/hello-world",title:"Hello World!",description:'The most basic application you can write is one which logs "Hello World!" and then exits.',source:"@site/docs/examples/hello-world.md",sourceDirName:"examples",slug:"/examples/hello-world",permalink:"/docs/examples/hello-world",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/hello-world.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Examples"},next:{title:"NodeJS Web Server",permalink:"/docs/examples/nodejs-web-server/implementation"}},s={},c=[{value:"Creating your First Service",id:"creating-your-first-service",level:2},{value:"The Root Service",id:"the-root-service",level:2},{value:"Using the Container",id:"using-the-container",level:2},{value:"Running our New App",id:"running-our-new-app",level:2}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"hello-world"},"Hello World!"),(0,o.kt)("p",null,'The most basic application you can write is one which logs "Hello World!" and then exits.\nTo give a basic demonstration of how TypeDI works, this is what we\'ll be doing today.'),(0,o.kt)("p",null,"To start, you'll want to make sure you've followed the instructions in ",(0,o.kt)("a",{parentName:"p",href:"../getting-started"},"Getting Started"),".\nThis will make sure you have a functioning environment to test TypeDI in."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"To run the examples below, you'll also want ",(0,o.kt)("a",{parentName:"p",href:"https://npmjs.org/ts-node"},"ts-node")," installed.\nThis will let us run TypeScript code without having to transpile it beforehand."),(0,o.kt)("pre",{parentName:"admonition"},(0,o.kt)("code",{parentName:"pre",className:"language-bash",metastring:"npm2yarn",npm2yarn:!0},"npm install -g ts-node\n")),(0,o.kt)("p",{parentName:"admonition"},"It's installed globally so it can be run from the command line, like ",(0,o.kt)("inlineCode",{parentName:"p"},"ts-node main.ts"),".")),(0,o.kt)("h2",{id:"creating-your-first-service"},"Creating your First Service"),(0,o.kt)("p",null,"To begin, you'll want to create your ",(0,o.kt)("inlineCode",{parentName:"p"},"log.service.ts")," file, which will contain the application logic to\nlog messages to the console. We'll then use this service later on to log a message!"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/log.service.ts"',title:'"src/log.service.ts"'},"import { Service } from '@freshgum/typedi';\n\n@Service([])\nexport class LogService {\n public log(message: string) {\n console.log(message);\n }\n}\n")),(0,o.kt)("p",null,"What we just did there was:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Declare a service named ",(0,o.kt)("inlineCode",{parentName:"li"},"LogService"),","),(0,o.kt)("li",{parentName:"ul"},"Tell TypeDI it has no dependencies on other services,"),(0,o.kt)("li",{parentName:"ul"},"Create a method on the service to log messages.")),(0,o.kt)("p",null,"Dependencies are a core concept of TypeDI, and Dependency Injection in general: ",(0,o.kt)("em",{parentName:"p"},"services can depend on other services!"),"\nThis lets us abstract our application logic away and place it into a neat little service, which we just did above."),(0,o.kt)("h2",{id:"the-root-service"},"The Root Service"),(0,o.kt)("p",null,'A typical convention in Dependency Injection is to create a "root service", which initialises other\nservices and ensures the environment is ready for them. Typically, an application will then call\na method on the root service to run the application.'),(0,o.kt)("p",null,"In our ",(0,o.kt)("inlineCode",{parentName:"p"},"root.service.ts")," file, we'll be doing just that."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { Service } from '@freshgum/typedi';\n\n@Service([LogService])\nexport class RootService {\n public constructor(private logger: LogService) {}\n\n run() {\n this.logger.log('Hello World!');\n }\n}\n")),(0,o.kt)("p",null,"We just declared a service named ",(0,o.kt)("inlineCode",{parentName:"p"},"RootService"),", which depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"LogService")," to log a message to the console.\nWe've told TypeDI our ",(0,o.kt)("inlineCode",{parentName:"p"},"RootService")," depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"LogService")," through the ",(0,o.kt)("inlineCode",{parentName:"p"},"@Service")," decorator, which is a fundamental\npart of the library. With it, you can declare services with a multitude of different configurations (but we'll get into that later)."),(0,o.kt)("h2",{id:"using-the-container"},"Using the Container"),(0,o.kt)("p",null,"Finally, to put everything together, we'll create a nice ",(0,o.kt)("inlineCode",{parentName:"p"},"main.ts")," file which starts the ",(0,o.kt)("inlineCode",{parentName:"p"},"RootService")," and calls its ",(0,o.kt)("inlineCode",{parentName:"p"},"run")," method."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@freshgum/typedi';\nimport { RootService } from './root.service';\n\nconst rootService = Container.get(RootService);\nrootService.run();\n")),(0,o.kt)("h2",{id:"running-our-new-app"},"Running our New App"),(0,o.kt)("p",null,"If you set up ",(0,o.kt)("inlineCode",{parentName:"p"},"ts-node")," as advised above, it'll be as simple as:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./src/main.ts\nHello World!\n")),(0,o.kt)("p",null,"I hear the questions already:"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"Wait... what? You gave it the name of the class, and it magically created an instance with the required dependencies?"),(0,o.kt)("p",{parentName:"blockquote"},"How does that work?")),(0,o.kt)("p",null,"Fear not! How TypeDI works is covered in the ",(0,o.kt)("a",{parentName:"p",href:"../guide/containers/introduction"},"Learning TypeDI")," section."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a8b2a833.a681ab19.js b/assets/js/a8b2a833.a681ab19.js deleted file mode 100644 index f8dc0bba..00000000 --- a/assets/js/a8b2a833.a681ab19.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[120],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var r=n(9496);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=o,h=d["".concat(s,".").concat(m)]||d[m]||u[m]||i;return n?r.createElement(h,a(a({ref:t},p),{},{components:n})):r.createElement(h,a({ref:t},p))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(1966),o=(n(9496),n(9613));const i={sidebar_position:1},a="Hello World!",l={unversionedId:"examples/hello-world",id:"examples/hello-world",title:"Hello World!",description:'The most basic application you can write is one which logs "Hello World!" and then exits.',source:"@site/docs/examples/hello-world.md",sourceDirName:"examples",slug:"/examples/hello-world",permalink:"/typedi/docs/examples/hello-world",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/hello-world.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Examples"},next:{title:"NodeJS Web Server",permalink:"/typedi/docs/examples/nodejs-web-server/implementation"}},s={},c=[{value:"Creating your First Service",id:"creating-your-first-service",level:2},{value:"The Root Service",id:"the-root-service",level:2},{value:"Using the Container",id:"using-the-container",level:2},{value:"Running our New App",id:"running-our-new-app",level:2}],p={toc:c},d="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(d,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"hello-world"},"Hello World!"),(0,o.kt)("p",null,'The most basic application you can write is one which logs "Hello World!" and then exits.\nTo give a basic demonstration of how TypeDI works, this is what we\'ll be doing today.'),(0,o.kt)("p",null,"To start, you'll want to make sure you've followed the instructions in ",(0,o.kt)("a",{parentName:"p",href:"../getting-started"},"Getting Started"),".\nThis will make sure you have a functioning environment to test TypeDI in."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"To run the examples below, you'll also want ",(0,o.kt)("a",{parentName:"p",href:"https://npmjs.org/ts-node"},"ts-node")," installed.\nThis will let us run TypeScript code without having to transpile it beforehand."),(0,o.kt)("pre",{parentName:"admonition"},(0,o.kt)("code",{parentName:"pre",className:"language-bash",metastring:"npm2yarn",npm2yarn:!0},"npm install -g ts-node\n")),(0,o.kt)("p",{parentName:"admonition"},"It's installed globally so it can be run from the command line, like ",(0,o.kt)("inlineCode",{parentName:"p"},"ts-node main.ts"),".")),(0,o.kt)("h2",{id:"creating-your-first-service"},"Creating your First Service"),(0,o.kt)("p",null,"To begin, you'll want to create your ",(0,o.kt)("inlineCode",{parentName:"p"},"log.service.ts")," file, which will contain the application logic to\nlog messages to the console. We'll then use this service later on to log a message!"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/log.service.ts"',title:'"src/log.service.ts"'},"import { Service } from '@typed-inject/injector';\n\n@Service([])\nexport class LogService {\n public log(message: string) {\n console.log(message);\n }\n}\n")),(0,o.kt)("p",null,"What we just did there was:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Declare a service named ",(0,o.kt)("inlineCode",{parentName:"li"},"LogService"),","),(0,o.kt)("li",{parentName:"ul"},"Tell TypeDI it has no dependencies on other services,"),(0,o.kt)("li",{parentName:"ul"},"Create a method on the service to log messages.")),(0,o.kt)("p",null,"Dependencies are a core concept of TypeDI, and Dependency Injection in general: ",(0,o.kt)("em",{parentName:"p"},"services can depend on other services!"),"\nThis lets us abstract our application logic away and place it into a neat little service, which we just did above."),(0,o.kt)("h2",{id:"the-root-service"},"The Root Service"),(0,o.kt)("p",null,'A typical convention in Dependency Injection is to create a "root service", which initialises other\nservices and ensures the environment is ready for them. Typically, an application will then call\na method on the root service to run the application.'),(0,o.kt)("p",null,"In our ",(0,o.kt)("inlineCode",{parentName:"p"},"root.service.ts")," file, we'll be doing just that."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { Service } from '@typed-inject/injector';\n\n@Service([LogService])\nexport class RootService {\n public constructor(private logger: LogService) {}\n\n run() {\n this.logger.log('Hello World!');\n }\n}\n")),(0,o.kt)("p",null,"We just declared a service named ",(0,o.kt)("inlineCode",{parentName:"p"},"RootService"),", which depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"LogService")," to log a message to the console.\nWe've told TypeDI our ",(0,o.kt)("inlineCode",{parentName:"p"},"RootService")," depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"LogService")," through the ",(0,o.kt)("inlineCode",{parentName:"p"},"@Service")," decorator, which is a fundamental\npart of the library. With it, you can declare services with a multitude of different configurations (but we'll get into that later)."),(0,o.kt)("h2",{id:"using-the-container"},"Using the Container"),(0,o.kt)("p",null,"Finally, to put everything together, we'll create a nice ",(0,o.kt)("inlineCode",{parentName:"p"},"main.ts")," file which starts the ",(0,o.kt)("inlineCode",{parentName:"p"},"RootService")," and calls its ",(0,o.kt)("inlineCode",{parentName:"p"},"run")," method."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/main.ts"',title:'"src/main.ts"'},"import { Container } from '@typed-inject/injector';\nimport { RootService } from './root.service';\n\nconst rootService = Container.get(RootService);\nrootService.run();\n")),(0,o.kt)("h2",{id:"running-our-new-app"},"Running our New App"),(0,o.kt)("p",null,"If you set up ",(0,o.kt)("inlineCode",{parentName:"p"},"ts-node")," as advised above, it'll be as simple as:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./src/main.ts\nHello World!\n")),(0,o.kt)("p",null,"I hear the questions already:"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"Wait... what? You gave it the name of the class, and it magically created an instance with the required dependencies?"),(0,o.kt)("p",{parentName:"blockquote"},"How does that work?")),(0,o.kt)("p",null,"Fear not! How TypeDI works is covered in the ",(0,o.kt)("a",{parentName:"p",href:"../guide/containers/introduction"},"Learning TypeDI")," section."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b27c2848.993481cc.js b/assets/js/b27c2848.993481cc.js deleted file mode 100644 index a612238f..00000000 --- a/assets/js/b27c2848.993481cc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[674],{9613:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>v});var r=n(9496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),u=a,v=d["".concat(l,".").concat(u)]||d[u]||m[u]||i;return n?r.createElement(v,o(o({ref:t},c),{},{components:n})):r.createElement(v,o({ref:t},c))}));function v(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(1966),a=(n(9496),n(9613));const i={sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},o="NodeJS Web Server",s={unversionedId:"examples/nodejs-web-server/implementation",id:"examples/nodejs-web-server/implementation",title:"NodeJS Web Server",description:"In the Services section, we talk about an implementation",source:"@site/docs/examples/nodejs-web-server/implementation.md",sourceDirName:"examples/nodejs-web-server",slug:"/examples/nodejs-web-server/implementation",permalink:"/typedi/docs/examples/nodejs-web-server/implementation",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/nodejs-web-server/implementation.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"Hello World!",permalink:"/typedi/docs/examples/hello-world"},next:{title:"Stopping Our App",permalink:"/typedi/docs/examples/nodejs-web-server/application-disposal"}},l={},p=[{value:"Creating our Web Server Service",id:"creating-our-web-server-service",level:2},{value:"Creating our RootService",id:"creating-our-rootservice",level:2},{value:"Adding a database",id:"adding-a-database",level:2},{value:"Updating our WebServerService",id:"updating-our-webserverservice",level:3}],c={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,a.kt)(d,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"nodejs-web-server"},"NodeJS Web Server"),(0,a.kt)("p",null,"In ",(0,a.kt)("a",{parentName:"p",href:"../../guide/services/introduction"},"the Services section"),", we talk about an implementation\nof a simple web server in TypeDI, through NodeJS and TypeScript."),(0,a.kt)("p",null,"The server would declare the following services:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"DatabaseService"),", for handling connections to the app's database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"WebServerService"),", which would handle the instantiation and management of your web server.")),(0,a.kt)("p",null,"In this example, we're going to look at implementing that server."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"To run the examples below, you'll also want ",(0,a.kt)("a",{parentName:"p",href:"https://npmjs.org/ts-node"},"ts-node")," installed.\nThis will let us run TypeScript code without having to transpile it beforehand."),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-bash",metastring:"npm2yarn",npm2yarn:!0},"npm install -g ts-node\n")),(0,a.kt)("p",{parentName:"admonition"},"It's installed globally so it can be run from the command line, like ",(0,a.kt)("inlineCode",{parentName:"p"},"ts-node main.ts"),".")),(0,a.kt)("h2",{id:"creating-our-web-server-service"},"Creating our Web Server Service"),(0,a.kt)("p",null,"The main part of our application is going to consist of a web-server and, as such,\nthat's what we're going to implement first."),(0,a.kt)("p",null,"To start, let's create a ",(0,a.kt)("inlineCode",{parentName:"p"},"webserver.service.ts")," which contains the logic for deploying the server,\nresponding to requests, and closing the server."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/webserver.service.ts"',title:'"src/webserver.service.ts"'},"import { Service } from '@typed-inject/injector';\nimport http, { Server, IncomingMessage, ServerResponse } from 'http'; // Node's HTTP module.\n\n@Service([])\nexport class WebServerService {\n private server!: Server;\n\n async startServer() {\n if (this.server?.listening) {\n return null;\n }\n\n const server = this.createServer();\n\n // Listen for connections on port 8080.\n // Make sure this isn't taken when you run the example!\n return server.listen(8080);\n }\n\n protected createServer() {\n return http.createServer((request, response) => this.handleRequest(request, response));\n }\n\n protected handleRequest(request: IncomingMessage, response: ServerResponse) {\n switch (response.url) {\n case '/hello':\n response.writeHead(200);\n response.end('Hello!');\n break;\n\n default:\n response.writeHead(404);\n response.end('Not Found');\n break;\n }\n }\n}\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"WebServerService")," supports the creation of the server and management of requests.\nThis lets it respond to HTTP requests from users."),(0,a.kt)("p",null,"This is a good start, ",(0,a.kt)("em",{parentName:"p"},"but we're not done yet...")),(0,a.kt)("h2",{id:"creating-our-rootservice"},"Creating our ",(0,a.kt)("inlineCode",{parentName:"h2"},"RootService")),(0,a.kt)("p",null,"To make our example run, we'll need something called a ",(0,a.kt)("em",{parentName:"p"},"root service"),".\nThis service will depend on our web server and start it."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"While not explicitly required, the root service pattern is recommended for applications.\nIt keeps your application initialisation code inside the context of a DI container, with\nas little as possible outside it.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { Service, Container } from '@typed-inject/injector';\nimport { WebServerService } from './webserver.service';\n\n@Service([WebServerService])\nexport class RootService {\n constructor(private webServer: WebServerService) {}\n\n async bootstrap() {\n return this.webServer.startServer();\n }\n}\n\n// If we're being run as \"$ ts-node root.service.ts\", start the server automatically.\nif (require.main === module) {\n const rootService = Container.get(RootService);\n rootService.bootstrap().then(() => console.log('Web server online!'));\n}\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Let's run our app!")," Run the following code:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./root.service.ts\n")),(0,a.kt)("p",null,"Now, navigate to ",(0,a.kt)("inlineCode",{parentName:"p"},"http://localhost:3000/hello")," and examine your work :-)"),(0,a.kt)("h2",{id:"adding-a-database"},"Adding a database"),(0,a.kt)("p",null,"As with any modern web application, we'll need a way to store inputs from users and then\noutput them at a later date. To do this, we'll be using a database."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("em",{parentName:"p"},"This section is skippable.")),(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("strong",{parentName:"p"},"We won't be setting up a database here.")," The example below makes use of a map to keep the example simple.")),(0,a.kt)("p",null,"We'll achieve this through a service which will read and write to an in-memory database.\nTo make it easier to migrate to an out-of-process database like SQLite later on, we'll also\nmake the APIs for reading and writing data asynchronous."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/database.service.ts"',title:'"src/database.service.ts"'},"import { Service } from '@typed-inject/injector';\n\n@Service([ ])\nexport const DatabaseService {\n private _map = new Map();\n\n async read (key: string) {\n this._map.get(key);\n }\n\n async write (key: string, value: string) {\n this._map.set(key, value);\n }\n}\n")),(0,a.kt)("h3",{id:"updating-our-webserverservice"},"Updating our ",(0,a.kt)("inlineCode",{parentName:"h3"},"WebServerService")),(0,a.kt)("p",null,"Now we have a database, we can update the web server to read and write values to it."),(0,a.kt)("p",null,"Let's update our web-server service with two new routes: one for reading a value, and another for writing it."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/webserver.service.ts"',title:'"src/webserver.service.ts"'},"// ...\n// highlight-revision-start\nimport { DatabaseService } from './database.service';\n// highlight-revision-end\n\n// highlight-revision-start\n@Service([DatabaseService])\n// highlight-revision-end\nclass WebServerService {\n // ...\n\n // highlight-revision-start\n constructor(private database: DatabaseService) {}\n // highlight-revision-end\n\n protected handleRequest(request: IncomingMessage, response: ServerResponse) {\n // highlight-revision-start\n const { searchParams: params } = new URL(request.url ?? '');\n // highlight-revision-end\n\n switch (response.url) {\n case '/hello':\n response.writeHead(200);\n // highlight-revision-start\n this.database.get('name').then(name => {\n response.end(`Hello, ${name ?? 'unknown person'}!`);\n });\n // highlight-revision-end\n break;\n\n case '/setname':\n response.writeHead(200);\n // highlight-revision-start\n this.database.set('name', params.name).then(() => {\n response.end(`Hello, ${params.name}!`);\n });\n // highlight-revision-end\n break;\n\n default:\n response.writeHead(404);\n response.end('Not Found');\n break;\n }\n }\n // ...\n}\n")),(0,a.kt)("p",null,"Now, we've got a functioning web-server which can store the user's name in memory.\nTry running the updated version, like so:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./root.service.ts\n")),(0,a.kt)("p",null,"Now, when we tell the server our name with ",(0,a.kt)("inlineCode",{parentName:"p"},"http://localhost:3000/setname?name=Joe"),",\nthe ",(0,a.kt)("inlineCode",{parentName:"p"},"/hello")," endpoint will address you by name! \ud83c\udf89"),(0,a.kt)("h2",{id:""}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b27c2848.b50282bd.js b/assets/js/b27c2848.b50282bd.js new file mode 100644 index 00000000..e22af9ee --- /dev/null +++ b/assets/js/b27c2848.b50282bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[674],{9613:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>v});var r=n(9496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=p(n),u=a,v=d["".concat(l,".").concat(u)]||d[u]||m[u]||i;return n?r.createElement(v,s(s({ref:t},c),{},{components:n})):r.createElement(v,s({ref:t},c))}));function v(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,s=new Array(i);s[0]=u;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:a,s[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>o,toc:()=>p});var r=n(1966),a=(n(9496),n(9613));const i={sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},s="NodeJS Web Server",o={unversionedId:"examples/nodejs-web-server/implementation",id:"examples/nodejs-web-server/implementation",title:"NodeJS Web Server",description:"In the Services section, we talk about an implementation",source:"@site/docs/examples/nodejs-web-server/implementation.md",sourceDirName:"examples/nodejs-web-server",slug:"/examples/nodejs-web-server/implementation",permalink:"/docs/examples/nodejs-web-server/implementation",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/nodejs-web-server/implementation.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"Hello World!",permalink:"/docs/examples/hello-world"},next:{title:"Stopping Our App",permalink:"/docs/examples/nodejs-web-server/application-disposal"}},l={},p=[{value:"Creating our Web Server Service",id:"creating-our-web-server-service",level:2},{value:"Creating our RootService",id:"creating-our-rootservice",level:2},{value:"Adding a database",id:"adding-a-database",level:2},{value:"Updating our WebServerService",id:"updating-our-webserverservice",level:3}],c={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,a.kt)(d,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"nodejs-web-server"},"NodeJS Web Server"),(0,a.kt)("p",null,"In ",(0,a.kt)("a",{parentName:"p",href:"../../guide/services/introduction"},"the Services section"),", we talk about an implementation\nof a simple web server in TypeDI, through NodeJS and TypeScript."),(0,a.kt)("p",null,"The server would declare the following services:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"DatabaseService"),", for handling connections to the app's database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"WebServerService"),", which would handle the instantiation and management of your web server.")),(0,a.kt)("p",null,"In this example, we're going to look at implementing that server."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"To run the examples below, you'll also want ",(0,a.kt)("a",{parentName:"p",href:"https://npmjs.org/ts-node"},"ts-node")," installed.\nThis will let us run TypeScript code without having to transpile it beforehand."),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-bash",metastring:"npm2yarn",npm2yarn:!0},"npm install -g ts-node\n")),(0,a.kt)("p",{parentName:"admonition"},"It's installed globally so it can be run from the command line, like ",(0,a.kt)("inlineCode",{parentName:"p"},"ts-node main.ts"),".")),(0,a.kt)("h2",{id:"creating-our-web-server-service"},"Creating our Web Server Service"),(0,a.kt)("p",null,"The main part of our application is going to consist of a web-server and, as such,\nthat's what we're going to implement first."),(0,a.kt)("p",null,"To start, let's create a ",(0,a.kt)("inlineCode",{parentName:"p"},"webserver.service.ts")," which contains the logic for deploying the server,\nresponding to requests, and closing the server."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/webserver.service.ts"',title:'"src/webserver.service.ts"'},"import { Service } from '@freshgum/typedi';\nimport http, { Server, IncomingMessage, ServerResponse } from 'http'; // Node's HTTP module.\n\n@Service([])\nexport class WebServerService {\n private server!: Server;\n\n async startServer() {\n if (this.server?.listening) {\n return null;\n }\n\n const server = this.createServer();\n\n // Listen for connections on port 8080.\n // Make sure this isn't taken when you run the example!\n return server.listen(8080);\n }\n\n protected createServer() {\n return http.createServer((request, response) => this.handleRequest(request, response));\n }\n\n protected handleRequest(request: IncomingMessage, response: ServerResponse) {\n switch (response.url) {\n case '/hello':\n response.writeHead(200);\n response.end('Hello!');\n break;\n\n default:\n response.writeHead(404);\n response.end('Not Found');\n break;\n }\n }\n}\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"WebServerService")," supports the creation of the server and management of requests.\nThis lets it respond to HTTP requests from users."),(0,a.kt)("p",null,"This is a good start, ",(0,a.kt)("em",{parentName:"p"},"but we're not done yet...")),(0,a.kt)("h2",{id:"creating-our-rootservice"},"Creating our ",(0,a.kt)("inlineCode",{parentName:"h2"},"RootService")),(0,a.kt)("p",null,"To make our example run, we'll need something called a ",(0,a.kt)("em",{parentName:"p"},"root service"),".\nThis service will depend on our web server and start it."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"While not explicitly required, the root service pattern is recommended for applications.\nIt keeps your application initialisation code inside the context of a DI container, with\nas little as possible outside it.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/root.service.ts"',title:'"src/root.service.ts"'},"import { Service, Container } from '@freshgum/typedi';\nimport { WebServerService } from './webserver.service';\n\n@Service([WebServerService])\nexport class RootService {\n constructor(private webServer: WebServerService) {}\n\n async bootstrap() {\n return this.webServer.startServer();\n }\n}\n\n// If we're being run as \"$ ts-node root.service.ts\", start the server automatically.\nif (require.main === module) {\n const rootService = Container.get(RootService);\n rootService.bootstrap().then(() => console.log('Web server online!'));\n}\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Let's run our app!")," Run the following code:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./root.service.ts\n")),(0,a.kt)("p",null,"Now, navigate to ",(0,a.kt)("inlineCode",{parentName:"p"},"http://localhost:3000/hello")," and examine your work :-)"),(0,a.kt)("h2",{id:"adding-a-database"},"Adding a database"),(0,a.kt)("p",null,"As with any modern web application, we'll need a way to store inputs from users and then\noutput them at a later date. To do this, we'll be using a database."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("em",{parentName:"p"},"This section is skippable.")),(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("strong",{parentName:"p"},"We won't be setting up a database here.")," The example below makes use of a map to keep the example simple.")),(0,a.kt)("p",null,"We'll achieve this through a service which will read and write to an in-memory database.\nTo make it easier to migrate to an out-of-process database like SQLite later on, we'll also\nmake the APIs for reading and writing data asynchronous."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/database.service.ts"',title:'"src/database.service.ts"'},"import { Service } from '@freshgum/typedi';\n\n@Service([ ])\nexport const DatabaseService {\n private _map = new Map();\n\n async read (key: string) {\n this._map.get(key);\n }\n\n async write (key: string, value: string) {\n this._map.set(key, value);\n }\n}\n")),(0,a.kt)("h3",{id:"updating-our-webserverservice"},"Updating our ",(0,a.kt)("inlineCode",{parentName:"h3"},"WebServerService")),(0,a.kt)("p",null,"Now we have a database, we can update the web server to read and write values to it."),(0,a.kt)("p",null,"Let's update our web-server service with two new routes: one for reading a value, and another for writing it."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="src/webserver.service.ts"',title:'"src/webserver.service.ts"'},"// ...\n// highlight-revision-start\nimport { DatabaseService } from './database.service';\n// highlight-revision-end\n\n// highlight-revision-start\n@Service([DatabaseService])\n// highlight-revision-end\nclass WebServerService {\n // ...\n\n // highlight-revision-start\n constructor(private database: DatabaseService) {}\n // highlight-revision-end\n\n protected handleRequest(request: IncomingMessage, response: ServerResponse) {\n // highlight-revision-start\n const { searchParams: params } = new URL(request.url ?? '');\n // highlight-revision-end\n\n switch (response.url) {\n case '/hello':\n response.writeHead(200);\n // highlight-revision-start\n this.database.get('name').then(name => {\n response.end(`Hello, ${name ?? 'unknown person'}!`);\n });\n // highlight-revision-end\n break;\n\n case '/setname':\n response.writeHead(200);\n // highlight-revision-start\n this.database.set('name', params.name).then(() => {\n response.end(`Hello, ${params.name}!`);\n });\n // highlight-revision-end\n break;\n\n default:\n response.writeHead(404);\n response.end('Not Found');\n break;\n }\n }\n // ...\n}\n")),(0,a.kt)("p",null,"Now, we've got a functioning web-server which can store the user's name in memory.\nTry running the updated version, like so:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"$ ts-node ./root.service.ts\n")),(0,a.kt)("p",null,"Now, when we tell the server our name with ",(0,a.kt)("inlineCode",{parentName:"p"},"http://localhost:3000/setname?name=Joe"),",\nthe ",(0,a.kt)("inlineCode",{parentName:"p"},"/hello")," endpoint will address you by name! \ud83c\udf89"),(0,a.kt)("h2",{id:""}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bdef968a.17f76d20.js b/assets/js/bdef968a.17f76d20.js deleted file mode 100644 index 6c122099..00000000 --- a/assets/js/bdef968a.17f76d20.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[425],{9613:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=i,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(m,a(a({ref:t},l),{},{components:n})):r.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(1966),i=(n(9496),n(9613));const o={sidebar_position:7},a="HostContainer",s={unversionedId:"guide/services/host-container",id:"guide/services/host-container",title:"HostContainer",description:"Sometimes, you'll encounter a situation within your app that",source:"@site/docs/guide/services/host-container.md",sourceDirName:"guide/services",slug:"/guide/services/host-container",permalink:"/typedi/docs/guide/services/host-container",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/host-container.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Usage in JavaScript",permalink:"/typedi/docs/guide/services/usage-in-javascript"},next:{title:"Eager Services",permalink:"/typedi/docs/guide/services/eager-services"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"hostcontainer"},"HostContainer"),(0,i.kt)("p",null,"Sometimes, you'll encounter a situation within your app that\nrequires breaking out of the more expressive decorator syntax."),(0,i.kt)("p",null,"This might be to check whether certain dependencies exist,\nor to perform any computations on the application's container."),(0,i.kt)("p",null,"To do this, TypeDI helpfully provides the ",(0,i.kt)("inlineCode",{parentName:"p"},"HostContainer")," function,\nwhich allows you to inject a service's executing container into\nthe service."),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"HostContainer is considered an ",(0,i.kt)("em",{parentName:"p"},'"escape hatch"'),", and it should be avoided where possible."),(0,i.kt)("p",{parentName:"admonition"},"This is called the Service Locator pattern, and it's only useful in certain scenarios.\nIn many cases, ",(0,i.kt)("a",{parentName:"p",href:"https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/"},"it's typically considered an anti-pattern"),". ",(0,i.kt)("sup",null,(0,i.kt)("a",{parentName:"p",href:"https://web.archive.org/web/20230208143016/https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/"},"(archive)"))),(0,i.kt)("p",{parentName:"admonition"},"If misused, it could mean that the dependencies of your serivce become opaque,\nwhere the only way to see what the service requires is to view its implementation.")),(0,i.kt)("p",null,"The HostContainer function returns a Token which, when passed to a DI container,\nresolves to the container itself. This means that the returned Token from ",(0,i.kt)("inlineCode",{parentName:"p"},"HostContainer")," can also be passed to ",(0,i.kt)("inlineCode",{parentName:"p"},"Container.get"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, HostContainer, Service } from '@typed-inject/injector';\n\n@Service([\n // highlight-revision-start\n HostContainer(),\n // highlight-revision-end\n])\nexport class MyService {\n // highlight-revision-start\n constructor(private container: ContainerInstance) {\n // highlight-revision-end\n if (container.has(MyService)) {\n console.log('Hello world!');\n }\n }\n}\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bdef968a.951df9ba.js b/assets/js/bdef968a.951df9ba.js new file mode 100644 index 00000000..351e6172 --- /dev/null +++ b/assets/js/bdef968a.951df9ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[425],{9613:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(9496);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=i,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(m,a(a({ref:t},l),{},{components:n})):r.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(1966),i=(n(9496),n(9613));const o={sidebar_position:7},a="HostContainer",s={unversionedId:"guide/services/host-container",id:"guide/services/host-container",title:"HostContainer",description:"Sometimes, you'll encounter a situation within your app that",source:"@site/docs/guide/services/host-container.md",sourceDirName:"guide/services",slug:"/guide/services/host-container",permalink:"/docs/guide/services/host-container",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/guide/services/host-container.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Usage in JavaScript",permalink:"/docs/guide/services/usage-in-javascript"},next:{title:"Eager Services",permalink:"/docs/guide/services/eager-services"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"hostcontainer"},"HostContainer"),(0,i.kt)("p",null,"Sometimes, you'll encounter a situation within your app that\nrequires breaking out of the more expressive decorator syntax."),(0,i.kt)("p",null,"This might be to check whether certain dependencies exist,\nor to perform any computations on the application's container."),(0,i.kt)("p",null,"To do this, TypeDI helpfully provides the ",(0,i.kt)("inlineCode",{parentName:"p"},"HostContainer")," function,\nwhich allows you to inject a service's executing container into\nthe service."),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"HostContainer is considered an ",(0,i.kt)("em",{parentName:"p"},'"escape hatch"'),", and it should be avoided where possible."),(0,i.kt)("p",{parentName:"admonition"},"This is called the Service Locator pattern, and it's only useful in certain scenarios.\nIn many cases, ",(0,i.kt)("a",{parentName:"p",href:"https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/"},"it's typically considered an anti-pattern"),". ",(0,i.kt)("sup",null,(0,i.kt)("a",{parentName:"p",href:"https://web.archive.org/web/20230208143016/https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/"},"(archive)"))),(0,i.kt)("p",{parentName:"admonition"},"If misused, it could mean that the dependencies of your serivce become opaque,\nwhere the only way to see what the service requires is to view its implementation.")),(0,i.kt)("p",null,"The HostContainer function returns a Token which, when passed to a DI container,\nresolves to the container itself. This means that the returned Token from ",(0,i.kt)("inlineCode",{parentName:"p"},"HostContainer")," can also be passed to ",(0,i.kt)("inlineCode",{parentName:"p"},"Container.get"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { ContainerInstance, HostContainer, Service } from '@freshgum/typedi';\n\n@Service([\n // highlight-revision-start\n HostContainer(),\n // highlight-revision-end\n])\nexport class MyService {\n // highlight-revision-start\n constructor(private container: ContainerInstance) {\n // highlight-revision-end\n if (container.has(MyService)) {\n console.log('Hello world!');\n }\n }\n}\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d10e8d20.7fb672e0.js b/assets/js/d10e8d20.7fb672e0.js deleted file mode 100644 index 3087651f..00000000 --- a/assets/js/d10e8d20.7fb672e0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[553],{9613:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var o=t(9496);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=o.createContext({}),c=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},p=function(e){var n=c(e.components);return o.createElement(s.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},m=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(t),m=i,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return t?o.createElement(f,a(a({ref:n},p),{},{components:t})):o.createElement(f,a({ref:n},p))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,a=new Array(r);a[0]=m;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[u]="string"==typeof e?e:i,a[1]=l;for(var c=2;c{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=t(1966),i=(t(9496),t(9613));const r={sidebar_position:2,title:"Code of Conduct"},a="Contributor Covenant Code of Conduct",l={unversionedId:"meta/code-of-conduct",id:"meta/code-of-conduct",title:"Code of Conduct",description:"Our Pledge",source:"@site/docs/meta/code-of-conduct.md",sourceDirName:"meta",slug:"/meta/code-of-conduct",permalink:"/typedi/docs/meta/code-of-conduct",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/meta/code-of-conduct.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,title:"Code of Conduct"},sidebar:"tutorialSidebar",previous:{title:"Contributing to TypeDI",permalink:"/typedi/docs/meta/contributing"},next:{title:"License",permalink:"/typedi/docs/meta/license"}},s={},c=[{value:"Our Pledge",id:"our-pledge",level:2},{value:"Our Standards",id:"our-standards",level:2},{value:"Enforcement Responsibilities",id:"enforcement-responsibilities",level:2},{value:"Scope",id:"scope",level:2},{value:"Enforcement",id:"enforcement",level:2},{value:"Enforcement Guidelines",id:"enforcement-guidelines",level:2},{value:"1. Correction",id:"1-correction",level:3},{value:"2. Warning",id:"2-warning",level:3},{value:"3. Temporary Ban",id:"3-temporary-ban",level:3},{value:"4. Permanent Ban",id:"4-permanent-ban",level:3},{value:"Attribution",id:"attribution",level:2}],p={toc:c},u="wrapper";function d(e){let{components:n,...t}=e;return(0,i.kt)(u,(0,o.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"contributor-covenant-code-of-conduct"},"Contributor Covenant Code of Conduct"),(0,i.kt)("h2",{id:"our-pledge"},"Our Pledge"),(0,i.kt)("p",null,"We as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation."),(0,i.kt)("p",null,"We pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community."),(0,i.kt)("h2",{id:"our-standards"},"Our Standards"),(0,i.kt)("p",null,"Examples of behavior that contributes to a positive environment for our\ncommunity include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Demonstrating empathy and kindness toward other people"),(0,i.kt)("li",{parentName:"ul"},"Being respectful of differing opinions, viewpoints, and experiences"),(0,i.kt)("li",{parentName:"ul"},"Giving and gracefully accepting constructive feedback"),(0,i.kt)("li",{parentName:"ul"},"Accepting responsibility and apologizing to those affected by our mistakes,\nand learning from the experience"),(0,i.kt)("li",{parentName:"ul"},"Focusing on what is best not just for us as individuals, but for the\noverall community")),(0,i.kt)("p",null,"Examples of unacceptable behavior include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The use of sexualized language or imagery, and sexual attention or\nadvances of any kind"),(0,i.kt)("li",{parentName:"ul"},"Trolling, insulting or derogatory comments, and personal or political attacks"),(0,i.kt)("li",{parentName:"ul"},"Public or private harassment"),(0,i.kt)("li",{parentName:"ul"},"Publishing others' private information, such as a physical or email\naddress, without their explicit permission"),(0,i.kt)("li",{parentName:"ul"},"Other conduct which could reasonably be considered inappropriate in a\nprofessional setting")),(0,i.kt)("h2",{id:"enforcement-responsibilities"},"Enforcement Responsibilities"),(0,i.kt)("p",null,"Community leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful."),(0,i.kt)("p",null,"Community leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate."),(0,i.kt)("h2",{id:"scope"},"Scope"),(0,i.kt)("p",null,"This Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event."),(0,i.kt)("h2",{id:"enforcement"},"Enforcement"),(0,i.kt)("p",null,"Instances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\n",(0,i.kt)("a",{parentName:"p",href:"mailto:freshgum.bubbles@protonmail.com."},"freshgum.bubbles@protonmail.com."),"\nAll complaints will be reviewed and investigated promptly and fairly."),(0,i.kt)("p",null,"All community leaders are obligated to respect the privacy and security of the\nreporter of any incident."),(0,i.kt)("h2",{id:"enforcement-guidelines"},"Enforcement Guidelines"),(0,i.kt)("p",null,"Community leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:"),(0,i.kt)("h3",{id:"1-correction"},"1. Correction"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested."),(0,i.kt)("h3",{id:"2-warning"},"2. Warning"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A violation through a single incident or series\nof actions."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban."),(0,i.kt)("h3",{id:"3-temporary-ban"},"3. Temporary Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A serious violation of community standards, including\nsustained inappropriate behavior."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban."),(0,i.kt)("h3",{id:"4-permanent-ban"},"4. Permanent Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A permanent ban from any sort of public interaction within\nthe community."),(0,i.kt)("h2",{id:"attribution"},"Attribution"),(0,i.kt)("p",null,"This Code of Conduct is adapted from the ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org"},"Contributor Covenant"),",\nversion 2.0, available at\n",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/version/2/0/code_of_conduct.html"},"https://www.contributor-covenant.org/version/2/0/code_of_conduct.html"),"."),(0,i.kt)("p",null,"Community Impact Guidelines were inspired by ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mozilla/diversity"},"Mozilla's code of conduct\nenforcement ladder"),"."),(0,i.kt)("p",null,"For answers to common questions about this code of conduct, see the FAQ at\n",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/faq"},"https://www.contributor-covenant.org/faq"),". Translations are available at\n",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/translations"},"https://www.contributor-covenant.org/translations"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d10e8d20.e9d8a91e.js b/assets/js/d10e8d20.e9d8a91e.js new file mode 100644 index 00000000..aa4ea25d --- /dev/null +++ b/assets/js/d10e8d20.e9d8a91e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[553],{9613:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var o=t(9496);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=o.createContext({}),c=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},p=function(e){var n=c(e.components);return o.createElement(s.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},m=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(t),m=i,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return t?o.createElement(f,a(a({ref:n},p),{},{components:t})):o.createElement(f,a({ref:n},p))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,a=new Array(r);a[0]=m;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[u]="string"==typeof e?e:i,a[1]=l;for(var c=2;c{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=t(1966),i=(t(9496),t(9613));const r={sidebar_position:2,title:"Code of Conduct"},a="Contributor Covenant Code of Conduct",l={unversionedId:"meta/code-of-conduct",id:"meta/code-of-conduct",title:"Code of Conduct",description:"Our Pledge",source:"@site/docs/meta/code-of-conduct.md",sourceDirName:"meta",slug:"/meta/code-of-conduct",permalink:"/docs/meta/code-of-conduct",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/meta/code-of-conduct.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,title:"Code of Conduct"},sidebar:"tutorialSidebar",previous:{title:"Contributing to TypeDI",permalink:"/docs/meta/contributing"},next:{title:"License",permalink:"/docs/meta/license"}},s={},c=[{value:"Our Pledge",id:"our-pledge",level:2},{value:"Our Standards",id:"our-standards",level:2},{value:"Enforcement Responsibilities",id:"enforcement-responsibilities",level:2},{value:"Scope",id:"scope",level:2},{value:"Enforcement",id:"enforcement",level:2},{value:"Enforcement Guidelines",id:"enforcement-guidelines",level:2},{value:"1. Correction",id:"1-correction",level:3},{value:"2. Warning",id:"2-warning",level:3},{value:"3. Temporary Ban",id:"3-temporary-ban",level:3},{value:"4. Permanent Ban",id:"4-permanent-ban",level:3},{value:"Attribution",id:"attribution",level:2}],p={toc:c},u="wrapper";function d(e){let{components:n,...t}=e;return(0,i.kt)(u,(0,o.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"contributor-covenant-code-of-conduct"},"Contributor Covenant Code of Conduct"),(0,i.kt)("h2",{id:"our-pledge"},"Our Pledge"),(0,i.kt)("p",null,"We as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation."),(0,i.kt)("p",null,"We pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community."),(0,i.kt)("h2",{id:"our-standards"},"Our Standards"),(0,i.kt)("p",null,"Examples of behavior that contributes to a positive environment for our\ncommunity include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Demonstrating empathy and kindness toward other people"),(0,i.kt)("li",{parentName:"ul"},"Being respectful of differing opinions, viewpoints, and experiences"),(0,i.kt)("li",{parentName:"ul"},"Giving and gracefully accepting constructive feedback"),(0,i.kt)("li",{parentName:"ul"},"Accepting responsibility and apologizing to those affected by our mistakes,\nand learning from the experience"),(0,i.kt)("li",{parentName:"ul"},"Focusing on what is best not just for us as individuals, but for the\noverall community")),(0,i.kt)("p",null,"Examples of unacceptable behavior include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The use of sexualized language or imagery, and sexual attention or\nadvances of any kind"),(0,i.kt)("li",{parentName:"ul"},"Trolling, insulting or derogatory comments, and personal or political attacks"),(0,i.kt)("li",{parentName:"ul"},"Public or private harassment"),(0,i.kt)("li",{parentName:"ul"},"Publishing others' private information, such as a physical or email\naddress, without their explicit permission"),(0,i.kt)("li",{parentName:"ul"},"Other conduct which could reasonably be considered inappropriate in a\nprofessional setting")),(0,i.kt)("h2",{id:"enforcement-responsibilities"},"Enforcement Responsibilities"),(0,i.kt)("p",null,"Community leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful."),(0,i.kt)("p",null,"Community leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate."),(0,i.kt)("h2",{id:"scope"},"Scope"),(0,i.kt)("p",null,"This Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event."),(0,i.kt)("h2",{id:"enforcement"},"Enforcement"),(0,i.kt)("p",null,"Instances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\n",(0,i.kt)("a",{parentName:"p",href:"mailto:freshgum.bubbles@protonmail.com."},"freshgum.bubbles@protonmail.com."),"\nAll complaints will be reviewed and investigated promptly and fairly."),(0,i.kt)("p",null,"All community leaders are obligated to respect the privacy and security of the\nreporter of any incident."),(0,i.kt)("h2",{id:"enforcement-guidelines"},"Enforcement Guidelines"),(0,i.kt)("p",null,"Community leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:"),(0,i.kt)("h3",{id:"1-correction"},"1. Correction"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested."),(0,i.kt)("h3",{id:"2-warning"},"2. Warning"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A violation through a single incident or series\nof actions."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban."),(0,i.kt)("h3",{id:"3-temporary-ban"},"3. Temporary Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A serious violation of community standards, including\nsustained inappropriate behavior."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban."),(0,i.kt)("h3",{id:"4-permanent-ban"},"4. Permanent Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A permanent ban from any sort of public interaction within\nthe community."),(0,i.kt)("h2",{id:"attribution"},"Attribution"),(0,i.kt)("p",null,"This Code of Conduct is adapted from the ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org"},"Contributor Covenant"),",\nversion 2.0, available at\n",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/version/2/0/code_of_conduct.html"},"https://www.contributor-covenant.org/version/2/0/code_of_conduct.html"),"."),(0,i.kt)("p",null,"Community Impact Guidelines were inspired by ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mozilla/diversity"},"Mozilla's code of conduct\nenforcement ladder"),"."),(0,i.kt)("p",null,"For answers to common questions about this code of conduct, see the FAQ at\n",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/faq"},"https://www.contributor-covenant.org/faq"),". Translations are available at\n",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/translations"},"https://www.contributor-covenant.org/translations"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dde0a8be.8807e4a0.js b/assets/js/dde0a8be.8807e4a0.js new file mode 100644 index 00000000..63caffe4 --- /dev/null +++ b/assets/js/dde0a8be.8807e4a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[670],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>O});var r=n(9496);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),d=o,O=u["".concat(s,".").concat(d)]||u[d]||f[d]||i;return n?r.createElement(O,a(a({ref:t},p),{},{components:n})):r.createElement(O,a({ref:t},p))}));function O(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(1966),o=(n(9496),n(9613));const i={sidebar_position:3},a="License",c={unversionedId:"meta/license",id:"meta/license",title:"License",description:"",source:"@site/docs/meta/license.md",sourceDirName:"meta",slug:"/meta/license",permalink:"/docs/meta/license",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/meta/license.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Code of Conduct",permalink:"/docs/meta/code-of-conduct"}},s={},l=[],p={toc:l},u="wrapper";function f(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"license"},"License"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'The MIT License\n\nCopyright (c) 2015-2021 TypeStack\nCopyright (c) 2023 freshgum (https://github.com/freshgum-bubbles)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the "Software"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dde0a8be.e14f11c5.js b/assets/js/dde0a8be.e14f11c5.js deleted file mode 100644 index 2b5a6b59..00000000 --- a/assets/js/dde0a8be.e14f11c5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[670],{9613:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>O});var r=n(9496);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),f=o,O=u["".concat(s,".").concat(f)]||u[f]||d[f]||i;return n?r.createElement(O,a(a({ref:t},p),{},{components:n})):r.createElement(O,a({ref:t},p))}));function O(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(1966),o=(n(9496),n(9613));const i={sidebar_position:3},a="License",c={unversionedId:"meta/license",id:"meta/license",title:"License",description:"",source:"@site/docs/meta/license.md",sourceDirName:"meta",slug:"/meta/license",permalink:"/typedi/docs/meta/license",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/meta/license.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Code of Conduct",permalink:"/typedi/docs/meta/code-of-conduct"}},s={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"license"},"License"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'The MIT License\n\nCopyright (c) 2015-2021 TypeStack\nCopyright (c) 2023 freshgum (https://github.com/freshgum-bubbles)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the "Software"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/eb1ab973.0f5c4678.js b/assets/js/eb1ab973.0f5c4678.js new file mode 100644 index 00000000..5a89531e --- /dev/null +++ b/assets/js/eb1ab973.0f5c4678.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[760],{9613:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(9496);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=c(n),m=o,f=u["".concat(p,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(1966),o=(n(9496),n(9613));const a={sidebar_position:3,title:"Adding Testing",sidebar_class_name:"sidebar_doc_incomplete"},i="Testing our App",s={unversionedId:"examples/nodejs-web-server/testing",id:"examples/nodejs-web-server/testing",title:"Adding Testing",description:"One primary advantage of using TypeDI, and Dependency Injection",source:"@site/docs/examples/nodejs-web-server/testing.md",sourceDirName:"examples/nodejs-web-server",slug:"/examples/nodejs-web-server/testing",permalink:"/docs/examples/nodejs-web-server/testing",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/nodejs-web-server/testing.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,title:"Adding Testing",sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"Stopping Our App",permalink:"/docs/examples/nodejs-web-server/application-disposal"},next:{title:"Containers",permalink:"/docs/guide/containers/introduction"}},p={},c=[],l={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"testing-our-app"},"Testing our App"),(0,o.kt)("p",null,"One primary advantage of using TypeDI, and Dependency Injection\nin general, is it greatly improves your ability to test individual\ncomponents in isolation, by providing them with different values and\nimplementations than would normally be present in your app."),(0,o.kt)("p",null,"For instance, consider the implementation of the HTTP server in\nthe previous example. In testing, we may not want it to ",(0,o.kt)("em",{parentName:"p"},"actually"),"\ncreate a HTTP server, though we ",(0,o.kt)("em",{parentName:"p"},"would")," want it to ensure it creates\na HTTP server successfully."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"For the examples below, we'll be making use of ",(0,o.kt)("a",{parentName:"p",href:"https://jestjs.io/"},"Jest"),".\nTests are written in an easy-to-follow format.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/eb1ab973.4ae66d14.js b/assets/js/eb1ab973.4ae66d14.js deleted file mode 100644 index 2c148e7d..00000000 --- a/assets/js/eb1ab973.4ae66d14.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[760],{9613:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(9496);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=c(n),m=o,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||i;return n?r.createElement(f,a(a({ref:t},l),{},{components:n})):r.createElement(f,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(1966),o=(n(9496),n(9613));const i={sidebar_position:3,title:"Adding Testing",sidebar_class_name:"sidebar_doc_incomplete"},a="Testing our App",s={unversionedId:"examples/nodejs-web-server/testing",id:"examples/nodejs-web-server/testing",title:"Adding Testing",description:"One primary advantage of using TypeDI, and Dependency Injection",source:"@site/docs/examples/nodejs-web-server/testing.md",sourceDirName:"examples/nodejs-web-server",slug:"/examples/nodejs-web-server/testing",permalink:"/typedi/docs/examples/nodejs-web-server/testing",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/examples/nodejs-web-server/testing.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,title:"Adding Testing",sidebar_class_name:"sidebar_doc_incomplete"},sidebar:"tutorialSidebar",previous:{title:"Stopping Our App",permalink:"/typedi/docs/examples/nodejs-web-server/application-disposal"},next:{title:"Containers",permalink:"/typedi/docs/guide/containers/introduction"}},p={},c=[],l={toc:c},d="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(d,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"testing-our-app"},"Testing our App"),(0,o.kt)("p",null,"One primary advantage of using TypeDI, and Dependency Injection\nin general, is it greatly improves your ability to test individual\ncomponents in isolation, by providing them with different values and\nimplementations than would normally be present in your app."),(0,o.kt)("p",null,"For instance, consider the implementation of the HTTP server in\nthe previous example. In testing, we may not want it to ",(0,o.kt)("em",{parentName:"p"},"actually"),"\ncreate a HTTP server, though we ",(0,o.kt)("em",{parentName:"p"},"would")," want it to ensure it creates\na HTTP server successfully."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"For the examples below, we'll be making use of ",(0,o.kt)("a",{parentName:"p",href:"https://jestjs.io/"},"Jest"),".\nTests are written in an easy-to-follow format.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.02395a04.js b/assets/js/main.02395a04.js deleted file mode 100644 index ebabea33..00000000 --- a/assets/js/main.02395a04.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.02395a04.js.LICENSE.txt */ -(self.webpackChunk_typed_inject_website=self.webpackChunk_typed_inject_website||[]).push([[179],{1139:(e,t,n)=>{var r={"./":1884};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=1139},8677:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(9496),a=n(1966),o=n(8832),i=n.n(o),l=n(6887);const s={"0e88606a":[()=>n.e(356).then(n.bind(n,7043)),"@site/docs/guide/containers/custom-containers.md",7043],17896441:[()=>Promise.all([n.e(532),n.e(517),n.e(141),n.e(552),n.e(918)]).then(n.bind(n,7946)),"@theme/DocItem",7946],"1a4e3797":[()=>Promise.all([n.e(532),n.e(920)]).then(n.bind(n,9134)),"@theme/SearchPage",9134],"1be78505":[()=>Promise.all([n.e(532),n.e(514)]).then(n.bind(n,7782)),"@theme/DocPage",7782],"1c20f44b":[()=>n.e(734).then(n.bind(n,4693)),"@site/docs/guide/containers/creating-containers.md",4693],"1df93b7f":[()=>Promise.all([n.e(532),n.e(517),n.e(21),n.e(237)]).then(n.bind(n,1089)),"@site/src/pages/index.tsx",1089],"1f391b9e":[()=>Promise.all([n.e(532),n.e(517),n.e(141),n.e(552),n.e(85)]).then(n.bind(n,2519)),"@theme/MDXPage",2519],"21c3df7e":[()=>n.e(440).then(n.bind(n,6004)),"@site/docs/guide/services/usage-in-javascript.md",6004],"3021cf83":[()=>Promise.all([n.e(532),n.e(517),n.e(538)]).then(n.bind(n,5747)),"@site/docs/getting-started.mdx",5747],"3334719e":[()=>n.e(300).then(n.bind(n,5617)),"@site/docs/examples/nodejs-web-server/application-disposal.md",5617],"37e83d0a":[()=>Promise.all([n.e(532),n.e(517),n.e(141),n.e(302)]).then(n.bind(n,1103)),"@site/docs/guide/services/resolution-constraints.mdx",1103],"393be207":[()=>n.e(414).then(n.bind(n,6326)),"@site/src/pages/markdown-page.md",6326],"3e3bd4e4":[()=>n.e(603).then(n.bind(n,1340)),"@site/docs/guide/services/introduction.md",1340],"3f288906":[()=>n.e(747).then(n.bind(n,4316)),"@site/docs/guide/services/multiple-services.md",4316],"45395bfd":[()=>n.e(856).then(n.bind(n,1717)),"@site/docs/guide/services/transient-services.mdx",1717],"4bd95d2f":[()=>n.e(706).then(n.t.bind(n,2776,19)),"/home/willhoskings/Documents/Development/typedi/docs/.docusaurus/@easyops-cn/docusaurus-search-local/default/plugin-route-context-module-100.json",2776],"531df37a":[()=>Promise.all([n.e(532),n.e(141),n.e(156)]).then(n.bind(n,9468)),"@site/docs/guide/containers/introduction.mdx",9468],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"6913d2c8":[()=>n.e(363).then(n.bind(n,1026)),"@site/docs/guide/services/singletons.md",1026],"72140a3c":[()=>n.e(962).then(n.bind(n,3520)),"@site/docs/migration/migrating-from-upstream-typedi.md",3520],"7281c5db":[()=>n.e(993).then(n.bind(n,9070)),"@site/docs/guide/react/introduction.md",9070],"8167aad2":[()=>n.e(463).then(n.bind(n,6075)),"@site/docs/guide/tokens/introduction.md",6075],89113871:[()=>n.e(309).then(n.bind(n,3698)),"@site/docs/meta/contributing.md",3698],"90cab2c2":[()=>n.e(112).then(n.t.bind(n,5745,19)),"/home/willhoskings/Documents/Development/typedi/docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"9d628f83":[()=>n.e(909).then(n.bind(n,5644)),"@site/docs/guide/services/eager-services.md",5644],a8b2a833:[()=>n.e(120).then(n.bind(n,6136)),"@site/docs/examples/hello-world.md",6136],a9d78703:[()=>n.e(94).then(n.t.bind(n,3769,19)),"/home/willhoskings/Documents/Development/typedi/docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],b27c2848:[()=>n.e(674).then(n.bind(n,3802)),"@site/docs/examples/nodejs-web-server/implementation.md",3802],bdef968a:[()=>n.e(425).then(n.bind(n,7126)),"@site/docs/guide/services/host-container.md",7126],d10e8d20:[()=>n.e(553).then(n.bind(n,1716)),"@site/docs/meta/code-of-conduct.md",1716],dde0a8be:[()=>n.e(670).then(n.bind(n,580)),"@site/docs/meta/license.md",580],eb1ab973:[()=>n.e(760).then(n.bind(n,5993)),"@site/docs/examples/nodejs-web-server/testing.md",5993]};function u(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var c=n(2800),d=n(9745);function p(e,t){if("*"===e)return i()({loading:u,loader:()=>n.e(106).then(n.bind(n,1106)),modules:["@theme/NotFound"],webpack:()=>[1106],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],p={},f=[],m=[],h=(0,c.Z)(o);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=s[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:u,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,a.Z)({},i,n)))}})}const f=[{path:"/typedi/markdown-page",component:p("/typedi/markdown-page","81d"),exact:!0},{path:"/typedi/search",component:p("/typedi/search","ce0"),exact:!0},{path:"/typedi/docs",component:p("/typedi/docs","ae9"),routes:[{path:"/typedi/docs/examples/hello-world",component:p("/typedi/docs/examples/hello-world","d6f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/examples/nodejs-web-server/application-disposal",component:p("/typedi/docs/examples/nodejs-web-server/application-disposal","195"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/examples/nodejs-web-server/implementation",component:p("/typedi/docs/examples/nodejs-web-server/implementation","22c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/examples/nodejs-web-server/testing",component:p("/typedi/docs/examples/nodejs-web-server/testing","b7b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/getting-started",component:p("/typedi/docs/getting-started","25b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/containers/creating-containers",component:p("/typedi/docs/guide/containers/creating-containers","382"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/containers/custom-containers",component:p("/typedi/docs/guide/containers/custom-containers","314"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/containers/introduction",component:p("/typedi/docs/guide/containers/introduction","9ae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/react/introduction",component:p("/typedi/docs/guide/react/introduction","0d1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/eager-services",component:p("/typedi/docs/guide/services/eager-services","cd0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/host-container",component:p("/typedi/docs/guide/services/host-container","314"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/introduction",component:p("/typedi/docs/guide/services/introduction","43b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/multiple-services",component:p("/typedi/docs/guide/services/multiple-services","86e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/resolution-constraints",component:p("/typedi/docs/guide/services/resolution-constraints","ecc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/singletons",component:p("/typedi/docs/guide/services/singletons","4a8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/transient-services",component:p("/typedi/docs/guide/services/transient-services","c3a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/services/usage-in-javascript",component:p("/typedi/docs/guide/services/usage-in-javascript","611"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/guide/tokens/introduction",component:p("/typedi/docs/guide/tokens/introduction","1b0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/meta/code-of-conduct",component:p("/typedi/docs/meta/code-of-conduct","0bc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/meta/contributing",component:p("/typedi/docs/meta/contributing","27a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/meta/license",component:p("/typedi/docs/meta/license","abb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/typedi/docs/migration/migrating-from-upstream-typedi",component:p("/typedi/docs/migration/migrating-from-upstream-typedi","c01"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/typedi/",component:p("/typedi/","f1d"),exact:!0},{path:"*",component:p("*")}]},9947:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(9496);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},3102:(e,t,n)=>{"use strict";var r=n(9496),a=n(7995),o=n(8736),i=n(8663),l=n(8347);const s=[n(7862),n(675),n(707),n(3613)];var u=n(8677),c=n(3442),d=n(1789),p=n(7215),f=n(1966),m=n(8379),h=n(9751),g=n(5650),v=n(6159),y=n(7445),b=n(7210),w=n(7089),k=n(3174),E=n(8029);function S(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,h.Z)(),n=(0,b.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function x(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),a=function(){const{siteConfig:{url:e}}=(0,h.Z)(),{pathname:t}=(0,c.TH)();return e+(0,g.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function C(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,v.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(y.d,{image:n}),r.createElement(x,null),r.createElement(S,null),r.createElement(E.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const _=new Map;function T(e){if(_.has(e.pathname))return{...e,pathname:_.get(e.pathname)};if((0,d.f)(u.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return _.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return _.set(e.pathname,t),{...e,pathname:t}}var L=n(9947),R=n(8563);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const A=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),P("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(u.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class N extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(A,{previousLocation:this.previousLocation,location:t},r.createElement(c.AW,{location:t,render:()=>e}))}}const I=N,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",F="__docusaurus-base-url-issue-banner-suggestion-container",j="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${j}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${j}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[j]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:D}))}function $(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.Z)(),{pathname:n}=(0,c.TH)();return t&&n===e?r.createElement(z,null):null}function U(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,h.Z)(),i=(0,g.Z)(e),{htmlLang:l,direction:s}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:l,dir:s}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var q=n(5861);function H(){const e=(0,d.H)(u.Z),t=(0,c.TH)();return r.createElement(q.Z,null,r.createElement(R.M,null,r.createElement(L.t,null,r.createElement(p.ZP,null,r.createElement(U,null),r.createElement(C,null),r.createElement($,null),r.createElement(I,{location:T(t)},e)))))}var G=n(6887);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Q=n(2800);const V=new Set,W=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Y={prefetch(e){if(!(e=>!K()&&!W.has(e)&&!V.has(e))(e))return!1;V.add(e);const t=(0,d.f)(u.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Q.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!W.has(e))(e)&&(W.add(e),O(e))},X=Object.freeze(Y);if(l.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;O(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(H,null))),document.getElementById("__docusaurus"))}))}},8563:(e,t,n)=>{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(9496),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/typedi/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/typedi/docs","mainDocId":"getting-started","docs":[{"id":"examples/hello-world","path":"/typedi/docs/examples/hello-world","sidebar":"tutorialSidebar"},{"id":"examples/nodejs-web-server/application-disposal","path":"/typedi/docs/examples/nodejs-web-server/application-disposal","sidebar":"tutorialSidebar"},{"id":"examples/nodejs-web-server/implementation","path":"/typedi/docs/examples/nodejs-web-server/implementation","sidebar":"tutorialSidebar"},{"id":"examples/nodejs-web-server/testing","path":"/typedi/docs/examples/nodejs-web-server/testing","sidebar":"tutorialSidebar"},{"id":"getting-started","path":"/typedi/docs/getting-started","sidebar":"tutorialSidebar"},{"id":"guide/containers/creating-containers","path":"/typedi/docs/guide/containers/creating-containers","sidebar":"tutorialSidebar"},{"id":"guide/containers/custom-containers","path":"/typedi/docs/guide/containers/custom-containers","sidebar":"tutorialSidebar"},{"id":"guide/containers/introduction","path":"/typedi/docs/guide/containers/introduction","sidebar":"tutorialSidebar"},{"id":"guide/react/introduction","path":"/typedi/docs/guide/react/introduction","sidebar":"tutorialSidebar"},{"id":"guide/services/eager-services","path":"/typedi/docs/guide/services/eager-services","sidebar":"tutorialSidebar"},{"id":"guide/services/host-container","path":"/typedi/docs/guide/services/host-container","sidebar":"tutorialSidebar"},{"id":"guide/services/introduction","path":"/typedi/docs/guide/services/introduction","sidebar":"tutorialSidebar"},{"id":"guide/services/multiple-services","path":"/typedi/docs/guide/services/multiple-services","sidebar":"tutorialSidebar"},{"id":"guide/services/resolution-constraints","path":"/typedi/docs/guide/services/resolution-constraints","sidebar":"tutorialSidebar"},{"id":"guide/services/singletons","path":"/typedi/docs/guide/services/singletons","sidebar":"tutorialSidebar"},{"id":"guide/services/transient-services","path":"/typedi/docs/guide/services/transient-services","sidebar":"tutorialSidebar"},{"id":"guide/services/usage-in-javascript","path":"/typedi/docs/guide/services/usage-in-javascript","sidebar":"tutorialSidebar"},{"id":"guide/tokens/introduction","path":"/typedi/docs/guide/tokens/introduction","sidebar":"tutorialSidebar"},{"id":"meta/code-of-conduct","path":"/typedi/docs/meta/code-of-conduct","sidebar":"tutorialSidebar"},{"id":"meta/contributing","path":"/typedi/docs/meta/contributing","sidebar":"tutorialSidebar"},{"id":"meta/license","path":"/typedi/docs/meta/license","sidebar":"tutorialSidebar"},{"id":"migration/migrating-from-upstream-typedi","path":"/typedi/docs/migration/migrating-from-upstream-typedi","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/typedi/docs/getting-started","label":"getting-started"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"2.4.1"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.35.0"}}}'),u={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},c=r.createContext(u);function d(e){let{children:t}=e;return r.createElement(c.Provider,{value:u},t)}},5861:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(9496),a=n(8347),o=n(8379),i=n(1161),l=n(5985);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(u,{error:t}))}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function c(e){let{error:t,tryAgain:n}=e;return r.createElement(p,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(c,e);class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},8347:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},8379:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(9496),a=n(8663);function o(e){return r.createElement(a.ql,e)}},5347:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(1966),a=n(9496),o=n(8736),i=n(1161),l=n(9751),s=n(8905),u=n(8347);const c=a.createContext({collectLink:()=>{}});var d=n(5650);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":g,autoAddBaseUrl:v=!0,...y}=e;const{siteConfig:{trailingSlash:b,baseUrl:w}}=(0,l.Z)(),{withBaseUrl:k}=(0,d.C)(),E=(0,a.useContext)(c),S=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>S.current));const x=p||f;const C=(0,s.Z)(x),_=x?.replace("pathname://","");let T=void 0!==_?(L=_,v&&(e=>e.startsWith("/"))(L)?k(L):L):void 0;var L;T&&C&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:b,baseUrl:w}));const R=(0,a.useRef)(!1),P=n?o.OL:o.rU,A=u.Z.canUseIntersectionObserver,O=(0,a.useRef)(),N=()=>{R.current||null==T||(window.docusaurus.preload(T),R.current=!0)};(0,a.useEffect)((()=>(!A&&C&&null!=T&&window.docusaurus.prefetch(T),()=>{A&&O.current&&O.current.disconnect()})),[O,T,A,C]);const I=T?.startsWith("#")??!1,D=!T||!C||I;return D||g||E.collectLink(T),D?a.createElement("a",(0,r.Z)({ref:S,href:T},x&&!C&&{target:"_blank",rel:"noopener noreferrer"},y)):a.createElement(P,(0,r.Z)({},y,{onMouseEnter:N,onTouchStart:N,innerRef:e=>{S.current=e,A&&e&&C&&(O.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),O.current.observe(e))},to:T},n&&{isActive:h,activeClassName:m}))}const f=a.forwardRef(p)},8197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,I:()=>l});var r=n(9496);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},5289:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},8905:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},5650:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(9496),a=n(9751),o=n(8905);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},9751:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(9496),a=n(8563);function o(){return(0,r.useContext)(a._)}},306:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(9496),a=n(9947);function o(){return(0,r.useContext)(a._)}},2800:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},9745:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(9496);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},8382:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>h,gA:()=>p,_r:()=>c,Jo:()=>g,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(3442),a=n(9751),o=n(5289);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},c=()=>i("docusaurus-plugin-content-docs")??u,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=c(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return s(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8832:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(9981),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},675:(e,t,n)=>{"use strict";n.r(t);var r=n(999),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(1139)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},8981:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(9496);const a={iconExternalLink:"iconExternalLink_EDmP"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},5985:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Ot});var r=n(9496),a=n(5924),o=n(5861),i=n(7445),l=n(1966),s=n(3442),u=n(8197),c=n(7632);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,u.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:a}=f();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,l.Z)({},e,{href:`#${d}`,onClick:a}),t))}var g=n(9262),v=n(7089);const y={skipToContent:"skipToContent_ncxO"};function b(){return r.createElement(h,{className:y.skipToContent})}var w=n(6159),k=n(2146);function E(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...s}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:t,height:n},s),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const S={closeButton:"closeButton_dIwu"};function x(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,u.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",S.closeButton,e.className)}),r.createElement(E,{width:14,height:14,strokeWidth:3.1}))}const C={content:"content_Yxav"};function _(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(C.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_IvQ_",announcementBarPlaceholder:"announcementBarPlaceholder_yLx0",announcementBarClose:"announcementBarClose_JGdf",announcementBarContent:"announcementBarContent_C2NL"};function L(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(_,{className:T.announcementBarContent}),i&&r.createElement(x,{onClick:n,className:T.announcementBarClose}))}var R=n(5731),P=n(4269);var A=n(2729),O=n(783);const N=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,R.e)(),t=(0,O.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,A.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(N.Provider,{value:n},t)}function D(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(N);if(!e)throw new A.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,O.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:D(o)})),[a,o,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var j=n(7384),B=n(306);function z(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function $(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const U={toggle:"toggle_nHBA",toggleButton:"toggleButton_gmen",darkToggleIcon:"darkToggleIcon_JP4D",lightToggleIcon:"lightToggleIcon_vSGv",toggleButtonDisabled:"toggleButtonDisabled_Zoqn"};function q(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const l=(0,B.Z)(),s=(0,u.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,u.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,u.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)(U.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",U.toggleButton,!l&&U.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!l,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)(U.toggleIcon,U.lightToggleIcon)}),r.createElement($,{className:(0,a.Z)(U.toggleIcon,U.darkToggleIcon)})))}const H=r.memo(q),G={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_KAdR"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,j.I)();return a?null:r.createElement(H,{className:t,buttonClassName:"dark"===n?G.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var Q=n(9361);function V(){return r.createElement(Q.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function W(){const e=(0,R.e)();return r.createElement("button",{type:"button","aria-label":(0,u.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(E,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(V,null),r.createElement(Z,{className:"margin-right--md"}),r.createElement(W,null))}var Y=n(5347),X=n(5650),J=n(8905);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(8981);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:s,isDropdownLink:u,prependBaseUrlToHref:c,...d}=e;const p=(0,X.Z)(a),f=(0,X.Z)(t),m=(0,X.Z)(o,{forcePrependBaseUrl:!0}),h=i&&o&&!(0,J.Z)(o),g=s?{dangerouslySetInnerHTML:{__html:s}}:{children:r.createElement(r.Fragment,null,i,h&&r.createElement(te.Z,u&&{width:12,height:12}))};return o?r.createElement(Y.Z,(0,l.Z)({href:c?m:o},d,g)):r.createElement(Y.Z,(0,l.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},d,g))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,l.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,l.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,l.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(4969),le=n(9927),se=n(9751);function ue(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ce(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const u=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{u.current&&!u.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[u]),r.createElement("div",{ref:u,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c})},r.createElement(ne,(0,l.Z)({"aria-haspopup":"true","aria-expanded":c,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},s,{onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))}}),s.children??s.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(Ge,(0,l.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...u}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[c,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(ne,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},u,{onClick:e=>{e.preventDefault(),f()}}),u.children??u.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(Ge,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function pe(e){let{mobile:t=!1,...n}=e;const a=t?de:ce;return r.createElement(a,n)}var fe=n(7210);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const he="iconLanguage_sxYh";var ge=n(4881),ve=n(8347),ye=n(1438),be=n(8382),we=n(1492),ke=n(9528),Ee=n(6035),Se=n(2181),xe=n(8285),Ce=n(3251);const _e='',Te='',Le='',Re='',Pe='',Ae='',Oe='',Ne={searchBar:"searchBar_v9WN",dropdownMenu:"dropdownMenu_H9dI",searchBarLeft:"searchBarLeft_vzjf",suggestion:"suggestion_RzOL",cursor:"cursor_iD9m",hitTree:"hitTree_gJ9G",hitIcon:"hitIcon_ShTb",hitPath:"hitPath_oZDo",noResultsIcon:"noResultsIcon_NJyk",hitFooter:"hitFooter_oSYT",hitWrapper:"hitWrapper_yppl",hitTitle:"hitTitle_MRMd",hitAction:"hitAction_yVTW",hideAction:"hideAction_Rkwz",noResults:"noResults_JXqe",searchBarContainer:"searchBarContainer_l1Am",searchBarLoadingRing:"searchBarLoadingRing_P6OK",searchClearButton:"searchClearButton_abOW",searchIndexLoading:"searchIndexLoading_nK61",searchHintContainer:"searchHintContainer_bWKb",searchHint:"searchHint__lDP",focused:"focused_pFRE",input:"input_fNcW",hint:"hint_Q8ob",suggestions:"suggestions_gDlj",dataset:"dataset_hnqq",empty:"empty_xAs3"};function Ie(e){let{document:t,type:n,page:r,metadata:a,tokens:o,isInterOfTree:i,isLastOfTree:l}=e;const s=0===n,u=1===n,c=[];i?c.push(Ae):l&&c.push(Oe);const d=c.map((e=>`${e}`)),p=`${s?_e:u?Te:Le}`,f=[`${(0,Ce.o)(t.t,(0,Se.m)(a,"t"),o)}`];if(!i&&!l&&ge.H6){const e=r?(r.b??[]).concat(r.t).concat(t.s&&t.s!==r.t?t.s:[]):t.b;f.push(`${(0,Ee.e)(e??[])}`)}else s||f.push(`${(0,xe.C)(r.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),o)}`);const m=`${Re}`;return[...d,p,``,...f,"",m].join("")}function De(){return`${Pe}${(0,u.I)({id:"theme.SearchBar.noResultsText",message:"No results"})}`}var Me=n(7180);async function Fe(){const e=await Promise.all([n.e(592),n.e(855)]).then(n.t.bind(n,9592,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const je="_highlight";const Be=function(e){let{handleSearchBarToggle:t}=e;const{siteConfig:{baseUrl:n}}=(0,se.Z)(),o=(0,be.gA)();let i=n;try{const{preferredVersion:e}=(0,ye.J)(o?.pluginId??ge.gQ);e&&!e.isLast&&(i=e.path+"/")}catch(D){if(ge.l9&&!(D instanceof A.i6))throw D}const l=(0,s.k6)(),c=(0,s.TH)(),d=(0,r.useRef)(null),p=(0,r.useRef)(new Map),f=(0,r.useRef)(!1),[m,h]=(0,r.useState)(!1),[g,v]=(0,r.useState)(!1),[y,b]=(0,r.useState)(""),w=(0,r.useRef)(null),k=(0,r.useRef)(""),[E,S]=(0,r.useState)("");(0,r.useEffect)((()=>{if(!Array.isArray(ge.Kc))return;let e="";if(c.pathname.startsWith(i)){const t=c.pathname.substring(i.length),n=ge.Kc.find((e=>t===e||t.startsWith(`${e}/`)));n&&(e=n)}k.current!==e&&(p.current.delete(e),k.current=e),S(e)}),[c.pathname,i]);const x=!!ge.hG&&Array.isArray(ge.Kc)&&""===E,C=(0,r.useCallback)((async()=>{if(x||p.current.get(E))return;p.current.set(E,"loading"),w.current?.autocomplete.destroy(),h(!0);const[{wrappedIndexes:e,zhDictionary:t},r]=await Promise.all([(0,we.w)(i,E),Fe()]);if(w.current=r(d.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,a.Z)(Ne.searchBar,{[Ne.searchBarLeft]:"left"===ge.pu}),noPrefix:!0,dropdownMenu:Ne.dropdownMenu,input:Ne.input,hint:Ne.hint,suggestions:Ne.suggestions,suggestion:Ne.suggestion,cursor:Ne.cursor,dataset:Ne.dataset,empty:Ne.empty}},[{source:(0,ke.v)(e,t,ge.qo),templates:{suggestion:Ie,empty:De,footer:e=>{let{query:t,isEmpty:r}=e;if(r&&!E)return;const a=(e=>{let{query:t,isEmpty:r}=e;const a=document.createElement("a"),o=new URLSearchParams,s=(0,u.I)({id:"theme.SearchBar.seeAll",message:"See all results"}),c=(0,u.I)({id:"theme.SearchBar.seeAllOutsideContext",message:"See results outside {context}"},{context:E}),d=(0,u.I)({id:"theme.SearchBar.searchInContext",message:"See all results in {context}"},{context:E});let p;if(o.set("q",t),p=E&&r?c:E?d:s,Array.isArray(ge.Kc)&&!r&&o.set("ctx",E),i!==n){if(!i.startsWith(n))throw new Error(`Version url '${i}' does not start with base url '${n}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);o.set("version",i.substring(n.length))}const f=`${n}search?${o.toString()}`;return a.href=f,a.textContent=p,a.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),w.current?.autocomplete.close(),l.push(f))})),a})({query:t,isEmpty:r}),o=document.createElement("div");return o.className=Ne.hitFooter,o.appendChild(a),o}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:r},tokens:a}=t;d.current?.blur();let o=n;if(ge.vc&&a.length>0){const e=new URLSearchParams;for(const t of a)e.append(je,t);o+=`?${e.toString()}`}r&&(o+=r),l.push(o)})).on("autocomplete:closed",(()=>{d.current?.blur()})),p.current.set(E,"done"),h(!1),f.current){const e=d.current;e.value&&w.current?.autocomplete.open(),e.focus()}}),[x,E,i,n,l]);(0,r.useEffect)((()=>{if(!ge.vc)return;const e=ve.Z.canUseDOM?new URLSearchParams(c.search).getAll(je):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new ge.vc(t);n.unmark(),0!==e.length&&n.mark(e),b(e.join(" ")),w.current?.autocomplete.setVal(e.join(" "))}))}),[c.search,c.pathname]);const[_,T]=(0,r.useState)(!1),L=(0,r.useCallback)((()=>{f.current=!0,C(),T(!0),t?.(!0)}),[t,C]),R=(0,r.useCallback)((()=>{T(!1),t?.(!1)}),[t]),P=(0,r.useCallback)((()=>{C()}),[C]),O=(0,r.useCallback)((e=>{b(e.target.value),e.target.value&&v(!0)}),[]),N=!!ve.Z.canUseDOM&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,r.useEffect)((()=>{if(!ge.AY)return;const e=e=>{!(N?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),d.current?.focus(),L())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[N,L]);const I=(0,r.useCallback)((()=>{const e=new URLSearchParams(c.search);e.delete(je);const t=e.toString(),n=c.pathname+(""!=t?`?${t}`:"")+c.hash;n!=c.pathname+c.search+c.hash&&l.push(n),b(""),w.current?.autocomplete.setVal("")}),[c.pathname,c.search,c.hash,l]);return r.createElement("div",{className:(0,a.Z)("navbar__search",Ne.searchBarContainer,{[Ne.searchIndexLoading]:m&&g,[Ne.focused]:_}),hidden:x},r.createElement("input",{placeholder:(0,u.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:P,onFocus:L,onBlur:R,onChange:O,ref:d,value:y}),r.createElement(Me.Z,{className:Ne.searchBarLoadingRing}),ge.AY&&ge.t_&&(""!==y?r.createElement("button",{className:Ne.searchClearButton,onClick:I},"\u2715"):ve.Z.canUseDOM&&r.createElement("div",{className:Ne.searchHintContainer},r.createElement("kbd",{className:Ne.searchHint},N?"\u2318":"ctrl"),r.createElement("kbd",{className:Ne.searchHint},"K"))))},ze={searchBox:"searchBox_tp3Z"};function $e(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,ze.searchBox)},t)}var Ue=n(8318);const qe=e=>e.docs.find((t=>t.id===e.mainDocId));const He={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,se.Z)(),p=(0,fe.l)(),{search:f,hash:m}=(0,s.TH)(),h=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],g=t?(0,u.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(pe,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:he}),g),items:h}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement($e,{className:n},r.createElement(Be,null))},dropdown:pe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,be.Iw)(a),s=(0,Ue.vY)(t,a);return null===s?null:r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.path===s.path||!!i?.sidebar&&i.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,be.Iw)(a),s=(0,Ue.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,Ue.lO)(a)[0],s=t??i.label,u=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,l.Z)({},o,{label:s,to:u}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...c}=e;const{search:d,hash:p}=(0,s.TH)(),f=(0,be.Iw)(n),m=(0,be.gB)(n),{savePreferredVersionName:h}=(0,ye.J)(n),g=[...o,...m.map((e=>{const t=f.alternateDocVersions[e.name]??qe(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>h(e.name)}})),...i],v=(0,Ue.lO)(n)[0],y=t&&g.length>1?(0,u.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):v.label,b=t&&g.length>1?void 0:qe(v).path;return g.length<=1?r.createElement(oe,(0,l.Z)({},c,{mobile:t,label:y,to:b,isActive:a?()=>!1:void 0})):r.createElement(pe,(0,l.Z)({},c,{mobile:t,label:y,to:b,items:g,isActive:a?()=>!1:void 0}))}};function Ge(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=He[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function Ze(){const e=(0,R.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(Ge,(0,l.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Qe(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(u.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Ve(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Qe,{onClick:()=>t.hide()}),t.content)}function We(){const e=(0,R.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(F,{header:r.createElement(K,null),primaryMenu:r.createElement(Ze,null),secondaryMenu:r.createElement(Ve,null)}):null}const Ke={navbarHideable:"navbarHideable_xzxR",navbarHidden:"navbarHidden_eJiE"};function Ye(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Xe(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,R.e)(),{navbarRef:l,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+u{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,"aria-label":(0,u.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ke.navbarHideable,!s&&Ke.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Ye,{onClick:i.toggle}),r.createElement(We,null))}var Je=n(1161);const et={errorBoundaryError:"errorBoundaryError_Na_F"};function tt(e){return r.createElement("button",(0,l.Z)({type:"button"},e),r.createElement(u.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function nt(e){let{error:t}=e;const n=(0,Je.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:et.errorBoundaryError},n)}class rt extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const at="right";function ot(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,l.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function it(){const{toggle:e,shown:t}=(0,R.e)();return r.createElement("button",{onClick:e,"aria-label":(0,u.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(ot,null))}const lt={colorModeToggle:"colorModeToggle_jEoN"};function st(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(rt,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},r.createElement(Ge,e)))))}function ut(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function ct(){const e=(0,R.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??at)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement(ut,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(it,null),r.createElement(V,null),r.createElement(st,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(st,{items:a}),r.createElement(Z,{className:lt.colorModeToggle}),!o&&r.createElement($e,null,r.createElement(Be,null)))})}function dt(){return r.createElement(Xe,null,r.createElement(ct,null))}function pt(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...s}=t,u=(0,X.Z)(n),c=(0,X.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(Y.Z,(0,l.Z)({className:"footer__link-item"},a?{href:i?c:a}:{to:u},s),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function ft(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(pt,{item:t}))}function mt(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(ft,{key:t,item:e})))))}function ht(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(mt,{key:t,column:e}))))}function gt(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function vt(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(pt,{item:t})}function yt(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(vt,{item:e}),t.length!==n+1&&r.createElement(gt,null))))))}function bt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(ht,{columns:t}):r.createElement(yt,{links:t})}var wt=n(5337);const kt={footerLogoLink:"footerLogoLink_psZt"};function Et(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(wt.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function St(e){let{logo:t}=e;return t.href?r.createElement(Y.Z,{href:t.href,className:kt.footerLogoLink,target:t.target},r.createElement(Et,{logo:t})):r.createElement(Et,{logo:t})}function xt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Ct(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function _t(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(Ct,{style:o,links:n&&n.length>0&&r.createElement(bt,{links:n}),logo:a&&r.createElement(St,{logo:a}),copyright:t&&r.createElement(xt,{copyright:t})})}const Tt=r.memo(_t),Lt=(0,A.Qc)([j.S,k.pl,P.OC,ye.L5,i.VC,function(e){let{children:t}=e;return r.createElement(O.n2,null,r.createElement(R.M,null,r.createElement(I,null,t)))}]);function Rt(e){let{children:t}=e;return r.createElement(Lt,null,t)}function Pt(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(u.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(tt,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(nt,{error:t})))))}const At={mainWrapper:"mainWrapper_fl_v"};function Ot(e){const{children:t,noFooter:n,wrapperClassName:l,title:s,description:u}=e;return(0,v.t)(),r.createElement(Rt,null,r.createElement(i.d,{title:s,description:u}),r.createElement(b,null),r.createElement(L,null),r.createElement(dt,null),r.createElement("div",{id:d,className:(0,a.Z)(g.k.wrapper.main,At.mainWrapper,l)},r.createElement(o.Z,{fallback:e=>r.createElement(Pt,e)},t)),!n&&r.createElement(Tt,null))}},9361:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1966),a=n(9496),o=n(5347),i=n(5650),l=n(9751),s=n(6159),u=n(5337);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},l=a.createElement(u.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},l):l}function d(e){const{siteConfig:{title:t}}=(0,l.Z)(),{navbar:{title:n,logo:u}}=(0,s.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.Z)(u?.href||"/"),h=n?"":t,g=u?.alt??h;return a.createElement(o.Z,(0,r.Z)({to:m},f,u?.target&&{target:u.target}),u&&a.createElement(c,{logo:u,alt:g,imageClassName:d}),null!=n&&a.createElement("b",{className:p},n))}},8029:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(9496),a=n(8379);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},5337:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(1966),a=n(9496),o=n(5924),i=n(306),l=n(7384);const s={themedImage:"themedImage_GG80","themedImage--light":"themedImage--light_ZgxF","themedImage--dark":"themedImage--dark_MYOw"};function u(e){const t=(0,i.Z)(),{colorMode:n}=(0,l.I)(),{sources:u,className:c,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,f.map((e=>a.createElement("img",(0,r.Z)({key:e,src:u[e],alt:d,className:(0,o.Z)(s.themedImage,s[`themedImage--${e}`],c)},p)))))}},4969:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>g});var r=n(1966),a=n(9496),o=n(8347),i=n(8821);const l="ease-in-out";function s(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const u={display:"none",overflow:"hidden",height:"0px"},c={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?u:c;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??l}`,height:`${t}px`}}function s(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function f(e){if(!o.Z.canUseDOM)return e?u:c}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:s}=e;const u=(0,a.useRef)(null);return p({collapsibleRef:u,collapsed:n,animation:o}),a.createElement(t,{ref:u,style:s?void 0:f(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(u.current,n),i?.(n))},className:l},r)}function h(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,s]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&s(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:l})):null}function g(e){let{lazy:t,...n}=e;const r=t?h:m;return a.createElement(r,n)}},2146:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(9496),a=n(306),o=n(671),i=n(2729),l=n(6159);const s=(0,o.WA)("docusaurus.announcement.dismiss"),u=(0,o.WA)("docusaurus.announcement.id"),c=()=>"true"===s.get(),d=e=>s.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&c()));(0,r.useEffect)((()=>{o(c())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&d(!1),!r&&c()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},7384:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>h});var r=n(9496),a=n(8347),o=n(2729),i=n(671),l=n(6159);const s=r.createContext(void 0),u="theme",c=(0,i.WA)(u),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>a.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{c.set(p(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,o]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&c.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),c.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=c.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(s.Provider,{value:n},t)}function g(){const e=(0,r.useContext)(s);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},1438:(e,t,n)=>{"use strict";n.d(t,{J:()=>y,L5:()=>g});var r=n(9496),a=n(8382),o=n(5289),i=n(6159),l=n(8318),s=n(2729),u=n(671);const c=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,u.WA)(c(e),{persistence:t}).set(n)},read:(e,t)=>(0,u.WA)(c(e),{persistence:t}).get(),clear:(e,t)=>{(0,u.WA)(c(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function g(e){let{children:t}=e;return l.cE?r.createElement(h,null,t):r.createElement(r.Fragment,null,t)}function v(){const e=(0,r.useContext)(f);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=v(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},6875:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(9496),a=n(2729);const o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},5731:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>p});var r=n(9496),a=n(783),o=n(7511),i=n(5399),l=n(6159),s=n(2729);const u=r.createContext(void 0);function c(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,l.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[s,u]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(s)return u(!1),!1}));const c=(0,r.useCallback)((()=>{u((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&u(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:s})),[e,n,c,s])}function d(e){let{children:t}=e;const n=c();return r.createElement(u.Provider,{value:n},t)}function p(){const e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},783:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(9496),a=n(2729);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,a.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},7089:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(9496);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7511:(e,t,n)=>{"use strict";n.d(t,{i:()=>u});var r=n(9496),a=n(8347);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=!1;function u(){const[e,t]=(0,r.useState)((()=>s?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},9262:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},8821:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},8318:(e,t,n)=>{"use strict";n.d(t,{Wl:()=>p,_F:()=>h,cE:()=>d,hI:()=>k,lO:()=>y,oz:()=>b,s1:()=>v,vY:()=>w});var r=n(9496),a=n(3442),o=n(1789),i=n(8382),l=n(1438),s=n(6875),u=n(2922),c=n(9927);const d=!!i._r;function p(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=p(t);if(e)return e}}}const f=(e,t)=>void 0!==e&&(0,c.Mg)(e,t),m=(e,t)=>e.some((e=>h(e,t)));function h(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||m(e.items,t))}function g(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,c.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,c.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function v(){const e=(0,s.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?g({sidebarItems:e.items,pathname:t}):null}function y(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>(0,u.j)([t,n,a].filter(Boolean))),[t,n,a])}function b(e,t){const n=y(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function w(e,t){const n=y(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function k(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,l=i.find((e=>(0,a.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,u=s?n.docsSidebars[s]:void 0;return{docElement:(0,o.H)(i),sidebarName:s,sidebarItems:u}}},5399:(e,t,n)=>{"use strict";n.d(t,{Rb:()=>l,_X:()=>s});var r=n(9496),a=n(3442),o=n(4241),i=n(2729);function l(e){!function(e){const t=(0,a.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){return function(e){const t=(0,a.k6)();return(0,o.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},2922:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function a(e){return Array.from(new Set(e))}n.d(t,{j:()=>a,l:()=>r})},7445:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>c,VC:()=>f});var r=n(9496),a=n(5924),o=n(8379),i=n(9745);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(5650),u=n(9751);function c(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const c=function(e){const{siteConfig:t}=(0,u.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),l)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function f(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,a.Z)(o,i)},t)}},2729:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>u,Ql:()=>s,i6:()=>l,zX:()=>o});var r=n(9496);const a=n(8347).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},9927:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(9496),a=n(8677),o=n(9751);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},4269:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>s,RF:()=>d,o5:()=>p});var r=n(9496),a=n(8347),o=n(306),i=n(2729);const l=r.createContext(void 0);function s(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(l.Provider,{value:n},t)}function u(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const c=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),a=(0,r.useRef)(c()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=c();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=u(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),a=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.useLayoutEffect)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:a}}function f(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3174:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(9751);const r="default";function a(e,t){return`docs-${e}-${t}`}},671:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>c});var r=n(9496),a=n(4241);const o="localStorage";function i(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function l(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const u={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=l(t?.persistence);return null===n?u:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),i({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),i({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?u:c(e,t))).current(),o=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,a.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},7210:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(9751),a=n(3442);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),l=o===n?e:e.replace(`/${o}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},7632:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(9496),a=n(3442),o=n(2729);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6159:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(9751);function a(){return(0,r.Z)().siteConfig.themeConfig}},8080:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},6772:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},1161:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8080);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(6772);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},7180:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(9496),a=n(5924);const o={loadingRing:"loadingRing_qPPM","loading-ring":"loading-ring_Auo_"};function i(e){let{className:t}=e;return r.createElement("div",{className:(0,a.Z)(o.loadingRing,t)},r.createElement("div",null),r.createElement("div",null),r.createElement("div",null),r.createElement("div",null))}},1492:(e,t,n)=>{"use strict";n.d(t,{w:()=>l});var r=n(7822),a=n.n(r),o=n(4881);const i=new Map;function l(e,t){const n=`${e}${t}`;let r=i.get(n);return r||(r=async function(e,t){{const n=`${e}${o.J.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),i=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:a().Index.load(r)}})),l=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:i,zhDictionary:Array.from(l)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),i.set(n,r)),r}},9528:(e,t,n)=>{"use strict";n.d(t,{v:()=>s});var r=n(7822),a=n.n(r);var o=n(4881);function i(e){return l(e).concat(l(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function l(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:a().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?a().Query.wildcard.TRAILING:a().Query.wildcard.NONE})))})))}function s(e,t,n){return function(r,l){const s=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return a()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,o.dK);if(0===s.length)return void l([]);const u=function(e,t){const n=function(e,t){const n=[];return function e(r,a){if(0===r.length)return void n.push(a);const o=r[0];if(/\p{Unified_Ideograph}/u.test(o)){const n=function(e,t){const n=[];return function e(r,a){let o=0,i=!1;for(const l of t)if(r.substr(0,l.length)===l){const t={missed:a.missed,term:a.term.concat({value:l})};r.length>l.length?e(r.substr(l.length),t):n.push(t),i=!0}else for(let t=l.length-1;t>o;t-=1){const s=l.substr(0,t);if(r.substr(0,t)===s){o=t;const l={missed:a.missed,term:a.term.concat({value:s,trailing:!0})};r.length>t?e(r.substr(t),l):n.push(l),i=!0;break}}i||(r.length>0?e(r.substr(1),{missed:a.missed+1,term:a.term}):a.term.length>0&&n.push(a))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(o,t);for(const t of n){const n=a.concat(...t);e(r.slice(1),n)}}else{const t=a.concat({value:o});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:a().Query.presence.REQUIRED,wildcard:a().Query.wildcard.LEADING|a().Query.wildcard.TRAILING})))}];for(const a of n)a[a.length-1].maybeTyping=!0;const r=[];for(const i of o.dK)if("en"===i)o._k||r.unshift(a().stopWordFilter);else{const e=a()[i];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let l;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);l=[];const t=[];for(const r of n){const n=e(r);l.push(n),n.length0&&t.push(n)}n.push(...t)}else l=n.slice();const s=[];for(const a of l)if(a.length>2)for(let e=a.length-1;e>=0;e-=1)s.push(a.slice(0,e).concat(a.slice(e+1)));return i(n).concat(i(s))}(s,t),c=[];e:for(const{term:t,tokens:a}of u)for(const{documents:r,index:o,type:i}of e)if(c.push(...o.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!c.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-c.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:i,page:0!==i&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:a,score:t.score}}))),c.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,a=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===r&&(r=t.index),-1===a&&(a=n.index),r===a?0===t.type?-1:0===n.type?1:t.index-n.index:r-a}))}(c),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n{"use strict";function r(e){return e.join(" \u203a ")}n.d(t,{e:()=>r})},3333:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{X:()=>r})},2181:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{m:()=>r})},8285:(e,t,n)=>{"use strict";n.d(t,{C:()=>a});var r=n(3333);function a(e,t,n){const o=[];for(const i of t){const n=e.toLowerCase().indexOf(i);if(n>=0){n>0&&o.push(a(e.substr(0,n),t)),o.push(`${(0,r.X)(e.substr(n,i.length))}`);const l=n+i.length;l${(0,r.X)(e)}`:(0,r.X)(e):o.join("")}},3251:(e,t,n)=>{"use strict";n.d(t,{o:()=>s});var r=n(3333),a=n(8285);const o=/\w+|\p{Unified_Ideograph}/u;function i(e){const t=[];let n=0,r=e;for(;r.length>0;){const a=r.match(o);if(!a){t.push(r);break}a.index>0&&t.push(r.substring(0,a.index)),t.push(a[0]),n+=a.index+a[0].length,r=e.substring(n)}return t}var l=n(4881);function s(e,t,n,o){void 0===o&&(o=l.Hk);const{chunkIndex:s,chunks:u}=function(e,t,n){const o=[];let l=0,s=0,u=-1;for(;ls){const t=i(e.substring(s,c)).map((e=>({html:(0,r.X)(e),textLength:e.length})));for(const e of t)o.push(e)}-1===u&&(u=o.length),s=c+d,o.push({html:(0,a.C)(e.substring(c,s),n,!0),textLength:d})}}if(s({html:(0,r.X)(e),textLength:e.length})));for(const e of t)o.push(e)}return{chunkIndex:u,chunks:o}}(e,t,n),c=u.slice(0,s),d=u[s],p=[d.html],f=u.slice(s+1);let m=d.textLength,h=0,g=0,v=!1,y=!1;for(;m0){const e=c.pop();m+e.textLength<=o?(p.unshift(e.html),h+=e.textLength,m+=e.textLength):(v=!0,c.length=0)}else{if(!(f.length>0))break;{const e=f.shift();m+e.textLength<=o?(p.push(e.html),g+=e.textLength,m+=e.textLength):(y=!0,f.length=0)}}return(v||c.length>0)&&p.unshift("\u2026"),(y||f.length>0)&&p.push("\u2026"),p.join("")}},4881:(e,t,n)=>{"use strict";n.d(t,{vc:()=>o,gQ:()=>f,H6:()=>u,hG:()=>g,l9:()=>m,dK:()=>r,_k:()=>a,pu:()=>p,AY:()=>c,t_:()=>d,Kc:()=>h,J:()=>i,Hk:()=>s,qo:()=>l,pQ:()=>v});n(7822);const r=["en"],a=!1,o=null,i="search-index{dir}.json?_=83874f22",l=8,s=50,u=!1,c=!0,d=!0,p="right",f=void 0,m=!0,h=null,g=!1,v=!1},7215:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>i});var r=n(9496);let a=function(e){return e.Production="production",e.Development="development",e}({});const o=r.createContext(a.Development);function i(e){let{children:t}=e;const n=(0,r.useMemo)((()=>{const e="production";return[a.Production,a.Development].includes(e)?e:a.Development}),[]);return r.createElement("div",{"data-environment":n},r.createElement(o.Provider,{value:n},t))}},5924:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>_,ob:()=>f,PP:()=>L,Ep:()=>p});var r=n(1966);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(8624);function s(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,h(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:b,goBack:function(){b(-1)},goForward:function(){b(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(6237),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=f(n);a&&a!==m&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),g=0;g{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,i,l],c=0;(s=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},901:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},7822:(e,t,n)=>{var r,a;!function(){var o,i,l,s,u,c,d,p,f,m,h,g,v,y,b,w,k,E,S,x,C,_,T,L,R,P,A,O,N,I,D=function(e){var t=new D.Builder;return t.pipeline.add(D.trimmer,D.stopWordFilter,D.stemmer),t.searchPipeline.add(D.stemmer),e.call(t,t),t.build()};D.version="2.3.9",D.utils={},D.utils.warn=(o=this,function(e){o.console&&console.warn&&console.warn(e)}),D.utils.asString=function(e){return null==e?"":e.toString()},D.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var s=D.utils.clone(t)||{};s.position=[i,l],s.index=a.length,a.push(new D.Token(n.slice(i,o),s))}i=o+1}}return a},D.tokenizer.separator=/[\s\-]+/,D.Pipeline=function(){this._stack=[]},D.Pipeline.registeredFunctions=Object.create(null),D.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&D.utils.warn("Overwriting existing registered function: "+t),e.label=t,D.Pipeline.registeredFunctions[e.label]=e},D.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||D.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},D.Pipeline.load=function(e){var t=new D.Pipeline;return e.forEach((function(e){var n=D.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},D.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){D.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},D.Pipeline.prototype.after=function(e,t){D.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},D.Pipeline.prototype.before=function(e,t){D.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},D.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},D.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(oe&&(n=a),o!=e);)r=n-t,a=t+Math.floor(r/2),o=this.elements[2*a];return o==e||o>e?2*a:ol?u+=2:i==l&&(t+=n[s+1]*r[u+1],s+=2,u+=2);return t},D.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},D.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var o,i=a.str.charAt(0);i in a.node.edges?o=a.node.edges[i]:(o=new D.TokenSet,a.node.edges[i]=o),1==a.str.length&&(o.final=!0),r.push({node:o,editsRemaining:a.editsRemaining,str:a.str.slice(1)})}if(0!=a.editsRemaining){if("*"in a.node.edges)var l=a.node.edges["*"];else{l=new D.TokenSet;a.node.edges["*"]=l}if(0==a.str.length&&(l.final=!0),r.push({node:l,editsRemaining:a.editsRemaining-1,str:a.str}),a.str.length>1&&r.push({node:a.node,editsRemaining:a.editsRemaining-1,str:a.str.slice(1)}),1==a.str.length&&(a.node.final=!0),a.str.length>=1){if("*"in a.node.edges)var s=a.node.edges["*"];else{s=new D.TokenSet;a.node.edges["*"]=s}1==a.str.length&&(s.final=!0),r.push({node:s,editsRemaining:a.editsRemaining-1,str:a.str.slice(1)})}if(a.str.length>1){var u,c=a.str.charAt(0),d=a.str.charAt(1);d in a.node.edges?u=a.node.edges[d]:(u=new D.TokenSet,a.node.edges[d]=u),1==a.str.length&&(u.final=!0),r.push({node:u,editsRemaining:a.editsRemaining-1,str:c+a.str.slice(2)})}}}return n},D.TokenSet.fromString=function(e){for(var t=new D.TokenSet,n=t,r=0,a=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},D.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},D.Index.prototype.search=function(e){return this.query((function(t){new D.QueryParser(e,t).parse()}))},D.Index.prototype.query=function(e){for(var t=new D.Query(this.fields),n=Object.create(null),r=Object.create(null),a=Object.create(null),o=Object.create(null),i=Object.create(null),l=0;l1?1:e},D.Builder.prototype.k1=function(e){this._k1=e},D.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var a=0;a=this.length)return D.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},D.QueryLexer.prototype.width=function(){return this.pos-this.start},D.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},D.QueryLexer.prototype.backup=function(){this.pos-=1},D.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=D.QueryLexer.EOS&&this.backup()},D.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(D.QueryLexer.TERM)),e.ignore(),e.more())return D.QueryLexer.lexText},D.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(D.QueryLexer.EDIT_DISTANCE),D.QueryLexer.lexText},D.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(D.QueryLexer.BOOST),D.QueryLexer.lexText},D.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(D.QueryLexer.TERM)},D.QueryLexer.termSeparator=D.tokenizer.separator,D.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==D.QueryLexer.EOS)return D.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return D.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(D.QueryLexer.TERM),D.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(D.QueryLexer.TERM),D.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(D.QueryLexer.PRESENCE),D.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(D.QueryLexer.PRESENCE),D.QueryLexer.lexText;if(t.match(D.QueryLexer.termSeparator))return D.QueryLexer.lexTerm}else e.escapeCharacter()}},D.QueryParser=function(e,t){this.lexer=new D.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},D.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=D.QueryParser.parseClause;e;)e=e(this);return this.query},D.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},D.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},D.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},D.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case D.QueryLexer.PRESENCE:return D.QueryParser.parsePresence;case D.QueryLexer.FIELD:return D.QueryParser.parseField;case D.QueryLexer.TERM:return D.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new D.QueryParseError(n,t.start,t.end)}},D.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=D.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=D.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new D.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new D.QueryParseError(n,t.start,t.end)}switch(r.type){case D.QueryLexer.FIELD:return D.QueryParser.parseField;case D.QueryLexer.TERM:return D.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new D.QueryParseError(n,r.start,r.end)}}},D.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new D.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var a=e.peekLexeme();if(null==a){r="expecting term, found nothing";throw new D.QueryParseError(r,t.start,t.end)}if(a.type===D.QueryLexer.TERM)return D.QueryParser.parseTerm;r="expecting term, found '"+a.type+"'";throw new D.QueryParseError(r,a.start,a.end)}},D.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case D.QueryLexer.TERM:return e.nextClause(),D.QueryParser.parseTerm;case D.QueryLexer.FIELD:return e.nextClause(),D.QueryParser.parseField;case D.QueryLexer.EDIT_DISTANCE:return D.QueryParser.parseEditDistance;case D.QueryLexer.BOOST:return D.QueryParser.parseBoost;case D.QueryLexer.PRESENCE:return e.nextClause(),D.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new D.QueryParseError(r,n.start,n.end)}else e.nextClause()}},D.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new D.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var a=e.peekLexeme();if(null!=a)switch(a.type){case D.QueryLexer.TERM:return e.nextClause(),D.QueryParser.parseTerm;case D.QueryLexer.FIELD:return e.nextClause(),D.QueryParser.parseField;case D.QueryLexer.EDIT_DISTANCE:return D.QueryParser.parseEditDistance;case D.QueryLexer.BOOST:return D.QueryParser.parseBoost;case D.QueryLexer.PRESENCE:return e.nextClause(),D.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+a.type+"'";throw new D.QueryParseError(r,a.start,a.end)}else e.nextClause()}},D.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new D.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var a=e.peekLexeme();if(null!=a)switch(a.type){case D.QueryLexer.TERM:return e.nextClause(),D.QueryParser.parseTerm;case D.QueryLexer.FIELD:return e.nextClause(),D.QueryParser.parseField;case D.QueryLexer.EDIT_DISTANCE:return D.QueryParser.parseEditDistance;case D.QueryLexer.BOOST:return D.QueryParser.parseBoost;case D.QueryLexer.PRESENCE:return e.nextClause(),D.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+a.type+"'";throw new D.QueryParseError(r,a.start,a.end)}else e.nextClause()}},void 0===(a="function"==typeof(r=function(){return D})?r.call(t,n,t,e):r)||(e.exports=a)}()},7862:(e,t,n)=>{"use strict";n.r(t)},3613:(e,t,n)=>{"use strict";n.r(t)},9981:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=p(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},2767:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s{var r=n(901);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=p;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",c=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],p=n[1],f=n.index;if(l+=e.slice(i,f),i=f+d.length,p)l+=p[1];else{var m=e[i],h=n[2],g=n[3],v=n[4],y=n[5],b=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=h&&null!=m&&m!==h,E="+"===b||"*"===b,S="?"===b||"*"===b,x=n[2]||c,C=v||y;r.push({name:g||o++,prefix:h||"",delimiter:x,optional:S,repeat:E,partial:k,asterisk:!!w,pattern:C?u(C):w?".*":"[^"+s(x)+"]+?"})}}return i{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);S+=E.value.length,E=E.next){var x=E.value;if(t.length>e.length)return;if(!(x instanceof a)){var C,_=1;if(y){if(!(C=o(k,S,e,v))||C.index>=e.length)break;var T=C.index,L=C.index+C[0].length,R=S;for(R+=E.value.length;T>=R;)R+=(E=E.next).value.length;if(S=R-=E.value.length,E.value instanceof a)continue;for(var P=E;P!==t.tail&&(Rd.reach&&(d.reach=I);var D=E.prev;if(O&&(D=s(t,D,O),S+=O.length),u(t,D,_),E=s(t,D,new a(p,g?r.tokenize(A,g):A,b,A)),N&&s(t,E,N),_>1){var M={cause:p+","+m,reach:I};i(e,t,n,E.prev,S,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=p(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s=0&&f(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function u(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function c(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,c={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return c[n]=a,n})).join(""),n,r),p=Object.keys(c);return i=0,function e(t){for(var n=0;n=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=p[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=u(c[a]),f=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),f){var h=[f];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=o.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],p="string"==typeof u?u:u.content,f=t(r,c),m=p.indexOf(f);if(m>-1){++a;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=p.substring(m+f.length),y=[];h&&y.push.apply(y,i([h])),y.push(g),v&&y.push.apply(y,i([v])),"string"==typeof u?l.splice.apply(l,[s,1].concat(y)):u.content=y}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},1064:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},1884:(e,t,n)=>{const r=n(1064),a=n(6474),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(2928).resolve(t)],delete Prism.languages[e],n(2928)(t),o.add(e)}))}i.silent=!1,e.exports=i},2928:(e,t,n)=>{var r={"./":1884};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=2928},6474:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var p,f=r(s),m=c;a(m);){for(var h in p={},m){var g=s[h];t(g&&g.modify,(function(e){e in d&&(p[e]=!0)}))}for(var v in d)if(!(v in c))for(var y in f(v))if(y in c){p[v]=!0;break}for(var b in m=p)c[b]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var a,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)a=r(e);else{var p=i(c.map((function(e){var t=u(e);return delete s[e],t})));o?a=o(p,(function(){return r(e)})):r(e)}return l[e]=a}for(var c in n)u(c);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,c,t,n)}};return w}}();e.exports=t},4049:(e,t,n)=>{"use strict";var r=n(6257);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},507:(e,t,n)=>{e.exports=n(4049)()},6257:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},7439:(e,t,n)=>{"use strict";var r=n(9496),a=n(2767),o=n(8051);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n