added tailwind back, reenabled utilities which was causing the color issue

This commit is contained in:
2026-04-30 23:25:30 -06:00
parent 1b2e1365d5
commit e95cbc5e41
716 changed files with 259826 additions and 309 deletions
+167 -167
View File
@@ -2,7 +2,7 @@
"hash": "8e064f63",
"configHash": "9602e671",
"lockfileHash": "2af5d584",
"browserHash": "96f57e4a",
"browserHash": "c9ed3368",
"optimized": {
"vue-router": {
"src": "../../vue-router/dist/vue-router.mjs",
@@ -19,487 +19,487 @@
"vuetify": {
"src": "../../vuetify/lib/framework.js",
"file": "vuetify.js",
"fileHash": "c6e98d38",
"fileHash": "a3d44ba9",
"needsInterop": false
},
"vuetify/components/VAlert": {
"src": "../../vuetify/lib/components/VAlert/index.js",
"file": "vuetify_components_VAlert.js",
"fileHash": "ab007c98",
"fileHash": "0494828d",
"needsInterop": false
},
"vuetify/components/VApp": {
"src": "../../vuetify/lib/components/VApp/index.js",
"file": "vuetify_components_VApp.js",
"fileHash": "f20430f7",
"fileHash": "8691f9fe",
"needsInterop": false
},
"vuetify/components/VAppBar": {
"src": "../../vuetify/lib/components/VAppBar/index.js",
"file": "vuetify_components_VAppBar.js",
"fileHash": "269d1d21",
"fileHash": "ef23c19d",
"needsInterop": false
},
"vuetify/components/VAvatar": {
"src": "../../vuetify/lib/components/VAvatar/index.js",
"file": "vuetify_components_VAvatar.js",
"fileHash": "ec01a545",
"fileHash": "5ce8925c",
"needsInterop": false
},
"vuetify/components/VBtn": {
"src": "../../vuetify/lib/components/VBtn/index.js",
"file": "vuetify_components_VBtn.js",
"fileHash": "0fcf61d0",
"fileHash": "cf4c48b6",
"needsInterop": false
},
"vuetify/components/VBtnToggle": {
"src": "../../vuetify/lib/components/VBtnToggle/index.js",
"file": "vuetify_components_VBtnToggle.js",
"fileHash": "639387a0",
"fileHash": "d1a4f67d",
"needsInterop": false
},
"vuetify/components/VCard": {
"src": "../../vuetify/lib/components/VCard/index.js",
"file": "vuetify_components_VCard.js",
"fileHash": "1fdfa6bf",
"fileHash": "baee0497",
"needsInterop": false
},
"vuetify/components/VChip": {
"src": "../../vuetify/lib/components/VChip/index.js",
"file": "vuetify_components_VChip.js",
"fileHash": "65e75ee4",
"fileHash": "40af6466",
"needsInterop": false
},
"vuetify/components/VCode": {
"src": "../../vuetify/lib/components/VCode/index.js",
"file": "vuetify_components_VCode.js",
"fileHash": "c2812980",
"fileHash": "73fb1a0d",
"needsInterop": false
},
"vuetify/components/VDataTable": {
"src": "../../vuetify/lib/components/VDataTable/index.js",
"file": "vuetify_components_VDataTable.js",
"fileHash": "a51c2fa4",
"fileHash": "0015d97a",
"needsInterop": false
},
"vuetify/components/VDialog": {
"src": "../../vuetify/lib/components/VDialog/index.js",
"file": "vuetify_components_VDialog.js",
"fileHash": "9634c8d8",
"fileHash": "96235b6a",
"needsInterop": false
},
"vuetify/components/VDivider": {
"src": "../../vuetify/lib/components/VDivider/index.js",
"file": "vuetify_components_VDivider.js",
"fileHash": "7aa6c03c",
"fileHash": "22b91c53",
"needsInterop": false
},
"vuetify/components/VEmptyState": {
"src": "../../vuetify/lib/components/VEmptyState/index.js",
"file": "vuetify_components_VEmptyState.js",
"fileHash": "85c1d869",
"fileHash": "6fcb7e7d",
"needsInterop": false
},
"vuetify/components/VExpansionPanel": {
"src": "../../vuetify/lib/components/VExpansionPanel/index.js",
"file": "vuetify_components_VExpansionPanel.js",
"fileHash": "a0026ebc",
"fileHash": "4b5f700a",
"needsInterop": false
},
"vuetify/components/VFileInput": {
"src": "../../vuetify/lib/components/VFileInput/index.js",
"file": "vuetify_components_VFileInput.js",
"fileHash": "b38829ad",
"fileHash": "767d6c24",
"needsInterop": false
},
"vuetify/components/VForm": {
"src": "../../vuetify/lib/components/VForm/index.js",
"file": "vuetify_components_VForm.js",
"fileHash": "ed25eb6f",
"fileHash": "f956317f",
"needsInterop": false
},
"vuetify/components/VGrid": {
"src": "../../vuetify/lib/components/VGrid/index.js",
"file": "vuetify_components_VGrid.js",
"fileHash": "a4bea739",
"fileHash": "4bbfc290",
"needsInterop": false
},
"vuetify/components/VIcon": {
"src": "../../vuetify/lib/components/VIcon/index.js",
"file": "vuetify_components_VIcon.js",
"fileHash": "539b5820",
"fileHash": "6bf4db8a",
"needsInterop": false
},
"vuetify/components/VImg": {
"src": "../../vuetify/lib/components/VImg/index.js",
"file": "vuetify_components_VImg.js",
"fileHash": "5753ddf7",
"fileHash": "9c4fdff1",
"needsInterop": false
},
"vuetify/components/VList": {
"src": "../../vuetify/lib/components/VList/index.js",
"file": "vuetify_components_VList.js",
"fileHash": "9322645a",
"fileHash": "14e9b6f5",
"needsInterop": false
},
"vuetify/components/VMain": {
"src": "../../vuetify/lib/components/VMain/index.js",
"file": "vuetify_components_VMain.js",
"fileHash": "33923772",
"fileHash": "818f7c3d",
"needsInterop": false
},
"vuetify/components/VMenu": {
"src": "../../vuetify/lib/components/VMenu/index.js",
"file": "vuetify_components_VMenu.js",
"fileHash": "8cecfbc2",
"fileHash": "6d91a786",
"needsInterop": false
},
"vuetify/components/VNavigationDrawer": {
"src": "../../vuetify/lib/components/VNavigationDrawer/index.js",
"file": "vuetify_components_VNavigationDrawer.js",
"fileHash": "32ab5ae0",
"fileHash": "7f6e5d05",
"needsInterop": false
},
"vuetify/components/VProgressLinear": {
"src": "../../vuetify/lib/components/VProgressLinear/index.js",
"file": "vuetify_components_VProgressLinear.js",
"fileHash": "9856819c",
"fileHash": "198b1e0f",
"needsInterop": false
},
"vuetify/components/VSelect": {
"src": "../../vuetify/lib/components/VSelect/index.js",
"file": "vuetify_components_VSelect.js",
"fileHash": "92807e93",
"fileHash": "a88065a3",
"needsInterop": false
},
"vuetify/components/VSheet": {
"src": "../../vuetify/lib/components/VSheet/index.js",
"file": "vuetify_components_VSheet.js",
"fileHash": "e87c90bb",
"fileHash": "bbb3fab6",
"needsInterop": false
},
"vuetify/components/VSnackbar": {
"src": "../../vuetify/lib/components/VSnackbar/index.js",
"file": "vuetify_components_VSnackbar.js",
"fileHash": "65283df8",
"fileHash": "13b79196",
"needsInterop": false
},
"vuetify/components/VSwitch": {
"src": "../../vuetify/lib/components/VSwitch/index.js",
"file": "vuetify_components_VSwitch.js",
"fileHash": "5798cdd3",
"fileHash": "e04d0dea",
"needsInterop": false
},
"vuetify/components/VTabs": {
"src": "../../vuetify/lib/components/VTabs/index.js",
"file": "vuetify_components_VTabs.js",
"fileHash": "05f9a354",
"fileHash": "ea54a15a",
"needsInterop": false
},
"vuetify/components/VTextField": {
"src": "../../vuetify/lib/components/VTextField/index.js",
"file": "vuetify_components_VTextField.js",
"fileHash": "6959b30d",
"fileHash": "2fdbd616",
"needsInterop": false
},
"vuetify/components/VTextarea": {
"src": "../../vuetify/lib/components/VTextarea/index.js",
"file": "vuetify_components_VTextarea.js",
"fileHash": "88df35a8",
"fileHash": "d7862242",
"needsInterop": false
},
"vuetify/components/VTimeline": {
"src": "../../vuetify/lib/components/VTimeline/index.js",
"file": "vuetify_components_VTimeline.js",
"fileHash": "dfc98cd0",
"fileHash": "f6ba4991",
"needsInterop": false
},
"vuetify/components/VToolbar": {
"src": "../../vuetify/lib/components/VToolbar/index.js",
"file": "vuetify_components_VToolbar.js",
"fileHash": "37534b0f",
"fileHash": "822ddc35",
"needsInterop": false
},
"vuetify/components/transitions": {
"src": "../../vuetify/lib/components/transitions/index.js",
"file": "vuetify_components_transitions.js",
"fileHash": "d7b77fc2",
"fileHash": "0f566edd",
"needsInterop": false
},
"vuetify/labs/VDateInput": {
"src": "../../vuetify/lib/labs/VDateInput/index.js",
"file": "vuetify_labs_VDateInput.js",
"fileHash": "25fd9cc8",
"fileHash": "682c9f40",
"needsInterop": false
}
},
"chunks": {
"VAvatar-DdzLb6e_": {
"file": "VAvatar-DdzLb6e_.js",
"VAvatar-BHEBKXii": {
"file": "VAvatar-BHEBKXii.js",
"isDynamicEntry": false
},
"VBadge-CiN6PgMV": {
"file": "VBadge-CiN6PgMV.js",
"VBadge-DTJk6Mtd": {
"file": "VBadge-DTJk6Mtd.js",
"isDynamicEntry": false
},
"VBtn-0bT-99qM": {
"file": "VBtn-0bT-99qM.js",
"VBtn-Bm4dgaEe": {
"file": "VBtn-Bm4dgaEe.js",
"isDynamicEntry": false
},
"VBtnToggle-COHI6AoR": {
"file": "VBtnToggle-COHI6AoR.js",
"VBtnToggle-BtUiWTgd": {
"file": "VBtnToggle-BtUiWTgd.js",
"isDynamicEntry": false
},
"VChip-CE9xKsuM": {
"file": "VChip-CE9xKsuM.js",
"VChip-D8z4sLH7": {
"file": "VChip-D8z4sLH7.js",
"isDynamicEntry": false
},
"VDefaultsProvider-CTN39wwv": {
"file": "VDefaultsProvider-CTN39wwv.js",
"VDefaultsProvider-C3Dl0By9": {
"file": "VDefaultsProvider-C3Dl0By9.js",
"isDynamicEntry": false
},
"VDivider-vMskEUvN": {
"file": "VDivider-vMskEUvN.js",
"VDivider-Bm22Quav": {
"file": "VDivider-Bm22Quav.js",
"isDynamicEntry": false
},
"VField-D15cm8qP": {
"file": "VField-D15cm8qP.js",
"VField-CDtYQTyk": {
"file": "VField-CDtYQTyk.js",
"isDynamicEntry": false
},
"VGrid-DPxB4khS": {
"file": "VGrid-DPxB4khS.js",
"VGrid-xu6tptBP": {
"file": "VGrid-xu6tptBP.js",
"isDynamicEntry": false
},
"VIcon-sEJi0XKP": {
"file": "VIcon-sEJi0XKP.js",
"VIcon-DqvHH35X": {
"file": "VIcon-DqvHH35X.js",
"isDynamicEntry": false
},
"VImg-B3K_zKHG": {
"file": "VImg-B3K_zKHG.js",
"VImg-D29ak-Ji": {
"file": "VImg-D29ak-Ji.js",
"isDynamicEntry": false
},
"VLabel-BWVZfhvb": {
"file": "VLabel-BWVZfhvb.js",
"VLabel-BK6j7Ce3": {
"file": "VLabel-BK6j7Ce3.js",
"isDynamicEntry": false
},
"VList-BPYFsjU7": {
"file": "VList-BPYFsjU7.js",
"VList-BhbWLtAc": {
"file": "VList-BhbWLtAc.js",
"isDynamicEntry": false
},
"VMenu-tK8Rb46Q": {
"file": "VMenu-tK8Rb46Q.js",
"VMenu-g8bPIWQQ": {
"file": "VMenu-g8bPIWQQ.js",
"isDynamicEntry": false
},
"VOverlay-CXGz5s5q": {
"file": "VOverlay-CXGz5s5q.js",
"VOverlay-BntBXXGT": {
"file": "VOverlay-BntBXXGT.js",
"isDynamicEntry": false
},
"VProgressCircular-BQ041Mfz": {
"file": "VProgressCircular-BQ041Mfz.js",
"VProgressCircular-z2FRmexp": {
"file": "VProgressCircular-z2FRmexp.js",
"isDynamicEntry": false
},
"VProgressLinear-DIOl79V8": {
"file": "VProgressLinear-DIOl79V8.js",
"VProgressLinear-Wk0zAkvE": {
"file": "VProgressLinear-Wk0zAkvE.js",
"isDynamicEntry": false
},
"VSelect-DP-1aJrD": {
"file": "VSelect-DP-1aJrD.js",
"VSelect-9P7g-lSZ": {
"file": "VSelect-9P7g-lSZ.js",
"isDynamicEntry": false
},
"VSelectionControl-CPYYRZWE": {
"file": "VSelectionControl-CPYYRZWE.js",
"VSelectionControl-DGk6dNy-": {
"file": "VSelectionControl-DGk6dNy-.js",
"isDynamicEntry": false
},
"VSheet-C9a054Bu": {
"file": "VSheet-C9a054Bu.js",
"VSheet-CdUUbWcK": {
"file": "VSheet-CdUUbWcK.js",
"isDynamicEntry": false
},
"VSlideGroup-CTSq2TjT": {
"file": "VSlideGroup-CTSq2TjT.js",
"VSlideGroup-CVNSOV5n": {
"file": "VSlideGroup-CVNSOV5n.js",
"isDynamicEntry": false
},
"VTextField-BAHlIp66": {
"file": "VTextField-BAHlIp66.js",
"VTextField-CbHSipIH": {
"file": "VTextField-CbHSipIH.js",
"isDynamicEntry": false
},
"VToolbar-CBjuzsOU": {
"file": "VToolbar-CBjuzsOU.js",
"VToolbar-DAPb7QHO": {
"file": "VToolbar-DAPb7QHO.js",
"isDynamicEntry": false
},
"anchor-fmhqx-jH": {
"file": "anchor-fmhqx-jH.js",
"anchor-Co261iQQ": {
"file": "anchor-Co261iQQ.js",
"isDynamicEntry": false
},
"animation-IGJS3o2f": {
"file": "animation-IGJS3o2f.js",
"animation-gSo9lwa6": {
"file": "animation-gSo9lwa6.js",
"isDynamicEntry": false
},
"autofocus-DSuuMpGE": {
"file": "autofocus-DSuuMpGE.js",
"autofocus-xE7ffHAe": {
"file": "autofocus-xE7ffHAe.js",
"isDynamicEntry": false
},
"border-BomwBLze": {
"file": "border-BomwBLze.js",
"border-DgwbzrV0": {
"file": "border-DgwbzrV0.js",
"isDynamicEntry": false
},
"box-De_BNjdi": {
"file": "box-De_BNjdi.js",
"box-BNWMOtF7": {
"file": "box-BNWMOtF7.js",
"isDynamicEntry": false
},
"color-CsNXUJXB": {
"file": "color-CsNXUJXB.js",
"color-B0NTWdor": {
"file": "color-B0NTWdor.js",
"isDynamicEntry": false
},
"colorUtils-CrR4MKb6": {
"file": "colorUtils-CrR4MKb6.js",
"colorUtils-CIHuTsPA": {
"file": "colorUtils-CIHuTsPA.js",
"isDynamicEntry": false
},
"component-cNt7KGbA": {
"file": "component-cNt7KGbA.js",
"component-W6F5nwNC": {
"file": "component-W6F5nwNC.js",
"isDynamicEntry": false
},
"createSimpleFunctional-CJfT4avK": {
"file": "createSimpleFunctional-CJfT4avK.js",
"createSimpleFunctional-DYAlCmHj": {
"file": "createSimpleFunctional-DYAlCmHj.js",
"isDynamicEntry": false
},
"date-DIfArSSH": {
"file": "date-DIfArSSH.js",
"date-DVxTP86R": {
"file": "date-DVxTP86R.js",
"isDynamicEntry": false
},
"deepEqual-tRUStdYj": {
"file": "deepEqual-tRUStdYj.js",
"deepEqual-BC7T2p7H": {
"file": "deepEqual-BC7T2p7H.js",
"isDynamicEntry": false
},
"defineComponent-92h8LsW-": {
"file": "defineComponent-92h8LsW-.js",
"defineComponent-D5UWd5Vb": {
"file": "defineComponent-D5UWd5Vb.js",
"isDynamicEntry": false
},
"density-D-xugoKB": {
"file": "density-D-xugoKB.js",
"density-Dey2iIaF": {
"file": "density-Dey2iIaF.js",
"isDynamicEntry": false
},
"dimensions-BOUfezru": {
"file": "dimensions-BOUfezru.js",
"dimensions-DYqEoPdw": {
"file": "dimensions-DYqEoPdw.js",
"isDynamicEntry": false
},
"display-NNQAdN_b": {
"file": "display-NNQAdN_b.js",
"display-BD8QD-8J": {
"file": "display-BD8QD-8J.js",
"isDynamicEntry": false
},
"easing-DfcvkbkS": {
"file": "easing-DfcvkbkS.js",
"isDynamicEntry": false
},
"elevation-B2sqdJV6": {
"file": "elevation-B2sqdJV6.js",
"elevation-DF9Lgrr_": {
"file": "elevation-DF9Lgrr_.js",
"isDynamicEntry": false
},
"focusTrap-5P1D0YbH": {
"file": "focusTrap-5P1D0YbH.js",
"focusTrap-BRlT3Jgx": {
"file": "focusTrap-BRlT3Jgx.js",
"isDynamicEntry": false
},
"form-aavUvMUm": {
"file": "form-aavUvMUm.js",
"form-DdDtsBxc": {
"file": "form-DdDtsBxc.js",
"isDynamicEntry": false
},
"forwardRefs-BgbYSFg3": {
"file": "forwardRefs-BgbYSFg3.js",
"forwardRefs-C50LZ3ti": {
"file": "forwardRefs-C50LZ3ti.js",
"isDynamicEntry": false
},
"getScrollParent-DuXs8SPu": {
"file": "getScrollParent-DuXs8SPu.js",
"isDynamicEntry": false
},
"goto-CD4cxzRn": {
"file": "goto-CD4cxzRn.js",
"goto-B27jmATn": {
"file": "goto-B27jmATn.js",
"isDynamicEntry": false
},
"group-Ba02qEMS": {
"file": "group-Ba02qEMS.js",
"group-sYL2sZpA": {
"file": "group-sYL2sZpA.js",
"isDynamicEntry": false
},
"icons-BqOQHwEN": {
"file": "icons-BqOQHwEN.js",
"icons-czM1t0u4": {
"file": "icons-czM1t0u4.js",
"isDynamicEntry": false
},
"intersect-B3zhL1Fk": {
"file": "intersect-B3zhL1Fk.js",
"intersect-CzF7r7uD": {
"file": "intersect-CzF7r7uD.js",
"isDynamicEntry": false
},
"layout-Booh7E97": {
"file": "layout-Booh7E97.js",
"layout-DcSzssSI": {
"file": "layout-DcSzssSI.js",
"isDynamicEntry": false
},
"lazy-CNRMZBuk": {
"file": "lazy-CNRMZBuk.js",
"lazy-CSlNPYYk": {
"file": "lazy-CSlNPYYk.js",
"isDynamicEntry": false
},
"loader-Cg-RQrUq": {
"file": "loader-Cg-RQrUq.js",
"loader-Dn_UJdiG": {
"file": "loader-Dn_UJdiG.js",
"isDynamicEntry": false
},
"locale-BI-ulWIe": {
"file": "locale-BI-ulWIe.js",
"locale-DTRSr4yu": {
"file": "locale-DTRSr4yu.js",
"isDynamicEntry": false
},
"location-Df6p1WYP": {
"file": "location-Df6p1WYP.js",
"location-DD-AfEFw": {
"file": "location-DD-AfEFw.js",
"isDynamicEntry": false
},
"position-ew5Obs9G": {
"file": "position-ew5Obs9G.js",
"position-7CDSPI1P": {
"file": "position-7CDSPI1P.js",
"isDynamicEntry": false
},
"proxiedModel-BI_mmSsi": {
"file": "proxiedModel-BI_mmSsi.js",
"proxiedModel-BOZtsMxA": {
"file": "proxiedModel-BOZtsMxA.js",
"isDynamicEntry": false
},
"resizeObserver-Cj_8nVae": {
"file": "resizeObserver-Cj_8nVae.js",
"resizeObserver-BhsZsTWI": {
"file": "resizeObserver-BhsZsTWI.js",
"isDynamicEntry": false
},
"ripple-BcjS5Kg8": {
"file": "ripple-BcjS5Kg8.js",
"ripple-Q8q1hNUv": {
"file": "ripple-Q8q1hNUv.js",
"isDynamicEntry": false
},
"rounded-zeYjdF6x": {
"file": "rounded-zeYjdF6x.js",
"rounded-m6mNMWh4": {
"file": "rounded-m6mNMWh4.js",
"isDynamicEntry": false
},
"router-CXIrojRO": {
"file": "router-CXIrojRO.js",
"router-CiYG9tKT": {
"file": "router-CiYG9tKT.js",
"isDynamicEntry": false
},
"scopeId-BhBMGBSS": {
"file": "scopeId-BhBMGBSS.js",
"scopeId-BbFYJclW": {
"file": "scopeId-BbFYJclW.js",
"isDynamicEntry": false
},
"ssrBoot-DPOmvdPm": {
"file": "ssrBoot-DPOmvdPm.js",
"ssrBoot-Dt2Wz9ZC": {
"file": "ssrBoot-Dt2Wz9ZC.js",
"isDynamicEntry": false
},
"tag-BzACG_PL": {
"file": "tag-BzACG_PL.js",
"tag-CIFqtlp2": {
"file": "tag-CIFqtlp2.js",
"isDynamicEntry": false
},
"theme-CwW_z-RC": {
"file": "theme-CwW_z-RC.js",
"theme-C1b955Ym": {
"file": "theme-C1b955Ym.js",
"isDynamicEntry": false
},
"transition-C2n5e2YD": {
"file": "transition-C2n5e2YD.js",
"transition-BieT_XBo": {
"file": "transition-BieT_XBo.js",
"isDynamicEntry": false
},
"transitions-CIB99T2D": {
"file": "transitions-CIB99T2D.js",
"transitions-llwxsiay": {
"file": "transitions-llwxsiay.js",
"isDynamicEntry": false
},
"useRender-kn3mcOTh": {
"file": "useRender-kn3mcOTh.js",
"useRender-DB_YiTtB": {
"file": "useRender-DB_YiTtB.js",
"isDynamicEntry": false
},
"variant-CXhPdVre": {
"file": "variant-CXhPdVre.js",
"variant-BcdnKFgE": {
"file": "variant-BcdnKFgE.js",
"isDynamicEntry": false
},
"vue.runtime.esm-bundler-BvoXUmaf": {
+8 -8
View File
@@ -1,12 +1,12 @@
import { Mn as effectScope, Ot as nextTick, U as computed, Vn as onScopeDispose, Wn as reactive, er as toValue, gn as watch, pt as h } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { G as mergeDeep, I as includes, a as createDefaults, ct as consoleWarn, i as DefaultsSymbol, nt as IN_BROWSER, s as useDefaults, t as defineComponent, ut as propsFactory, z as isObject } from "./defineComponent-92h8LsW-.js";
import { a as useLayout } from "./layout-Booh7E97.js";
import { i as useRtl, n as createLocale, r as useLocale, t as LocaleSymbol } from "./locale-BI-ulWIe.js";
import { a as useTheme, n as createTheme, t as ThemeSymbol } from "./theme-CwW_z-RC.js";
import { o as VSvgIcon, r as VClassIcon, t as IconSymbol } from "./icons-BqOQHwEN.js";
import { a as useDisplay, r as createDisplay, t as DisplaySymbol } from "./display-NNQAdN_b.js";
import { n as DateOptionsSymbol, o as useDate, r as createDate, t as DateAdapterSymbol } from "./date-DIfArSSH.js";
import { n as createGoTo, r as useGoTo, t as GoToSymbol } from "./goto-CD4cxzRn.js";
import { B as isObject, K as mergeDeep, L as includes, a as createDefaults, i as DefaultsSymbol, lt as consoleWarn, rt as IN_BROWSER, s as useDefaults, t as defineComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { o as VSvgIcon, r as VClassIcon, t as IconSymbol } from "./icons-czM1t0u4.js";
import { a as useTheme, n as createTheme, t as ThemeSymbol } from "./theme-C1b955Ym.js";
import { i as useRtl, n as createLocale, r as useLocale, t as LocaleSymbol } from "./locale-DTRSr4yu.js";
import { a as useLayout } from "./layout-DcSzssSI.js";
import { a as useDisplay, r as createDisplay, t as DisplaySymbol } from "./display-BD8QD-8J.js";
import { n as DateOptionsSymbol, o as useDate, r as createDate, t as DateAdapterSymbol } from "./date-DVxTP86R.js";
import { n as createGoTo, r as useGoTo, t as GoToSymbol } from "./goto-B27jmATn.js";
//#region node_modules/vuetify/lib/composables/hotkey/key-aliases.js
/**
* Centralized key alias mapping for consistent key normalization across the hotkey system.
+6 -6
View File
@@ -1,10 +1,10 @@
import { W as createBaseVNode, ar as normalizeClass, sr as normalizeStyle } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { K as omit, r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as makeComponentProps } from "./component-cNt7KGbA.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { i as makeLayoutProps, n as createLayout } from "./layout-Booh7E97.js";
import { i as useRtl } from "./locale-BI-ulWIe.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-CwW_z-RC.js";
import { q as omit, r as genericComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { t as makeComponentProps } from "./component-W6F5nwNC.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-C1b955Ym.js";
import { i as useRtl } from "./locale-DTRSr4yu.js";
import { i as makeLayoutProps, n as createLayout } from "./layout-DcSzssSI.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VApp/VApp.css";
//#region node_modules/vuetify/lib/components/VApp/VApp.js
var makeVAppProps = propsFactory({
+7 -7
View File
@@ -1,11 +1,11 @@
import { Dt as mergeProps, Ft as onMounted, Kn as ref, Qn as toRef, U as computed, Yn as shallowRef, _n as watchEffect, et as createVNode, gn as watch, jt as onBeforeUnmount } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { K as omit, ct as consoleWarn, g as clamp, r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { o as useLayoutItem, r as makeLayoutItemProps } from "./layout-Booh7E97.js";
import { n as useToggleScope, t as useProxiedModel } from "./proxiedModel-BI_mmSsi.js";
import { i as makeVToolbarTitleProps, n as makeVToolbarProps, r as VToolbarTitle, t as VToolbar } from "./VToolbar-CBjuzsOU.js";
import { t as useSsrBoot } from "./ssrBoot-DPOmvdPm.js";
import { n as makeVBtnProps, t as VBtn } from "./VBtn-0bT-99qM.js";
import { _ as clamp, lt as consoleWarn, q as omit, r as genericComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { n as useToggleScope, t as useProxiedModel } from "./proxiedModel-BOZtsMxA.js";
import { o as useLayoutItem, r as makeLayoutItemProps } from "./layout-DcSzssSI.js";
import { t as useSsrBoot } from "./ssrBoot-Dt2Wz9ZC.js";
import { i as makeVToolbarTitleProps, n as makeVToolbarProps, r as VToolbarTitle, t as VToolbar } from "./VToolbar-DAPb7QHO.js";
import { n as makeVBtnProps, t as VBtn } from "./VBtn-Bm4dgaEe.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VAppBar/VAppBar.css";
//#region node_modules/vuetify/lib/composables/scroll.js
var makeScrollProps = propsFactory({
+1 -1
View File
@@ -1,2 +1,2 @@
import { t as VAvatar } from "./VAvatar-DdzLb6e_.js";
import { t as VAvatar } from "./VAvatar-BHEBKXii.js";
export { VAvatar };
+1 -1
View File
@@ -1,2 +1,2 @@
import { t as VBtn } from "./VBtn-0bT-99qM.js";
import { t as VBtn } from "./VBtn-Bm4dgaEe.js";
export { VBtn };
+22 -22
View File
@@ -1,26 +1,26 @@
import { Cn as withDirectives, Dt as mergeProps, M as Fragment, W as createBaseVNode, Yn as shallowRef, ar as normalizeClass, cr as toDisplayString, et as createVNode, gn as watch, sr as normalizeStyle } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { _ as convertToUnit, o as provideDefaults, r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as makeComponentProps } from "./component-cNt7KGbA.js";
import { t as createSimpleFunctional } from "./createSimpleFunctional-CJfT4avK.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-CwW_z-RC.js";
import { t as makeTagProps } from "./tag-BzACG_PL.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-CTN39wwv.js";
import { n as useDimension, t as makeDimensionProps } from "./dimensions-BOUfezru.js";
import { t as VImg } from "./VImg-B3K_zKHG.js";
import { n as useRounded, t as makeRoundedProps } from "./rounded-zeYjdF6x.js";
import { n as useBorder, t as makeBorderProps } from "./border-BomwBLze.js";
import { n as useElevation, t as makeElevationProps } from "./elevation-B2sqdJV6.js";
import { n as useLocation, t as makeLocationProps } from "./location-Df6p1WYP.js";
import { n as useDensity, t as makeDensityProps } from "./density-D-xugoKB.js";
import { n as makeVariantProps, r as useVariant, t as genOverlays } from "./variant-CXhPdVre.js";
import { n as IconValue } from "./icons-BqOQHwEN.js";
import { t as VIcon } from "./VIcon-sEJi0XKP.js";
import { n as makeLoaderProps, r as useLoader, t as LoaderSlot } from "./loader-Cg-RQrUq.js";
import { n as usePosition, t as makePositionProps } from "./position-ew5Obs9G.js";
import { r as useLink, t as makeRouterProps } from "./router-CXIrojRO.js";
import { t as Ripple } from "./ripple-BcjS5Kg8.js";
import { t as VAvatar } from "./VAvatar-DdzLb6e_.js";
import { o as provideDefaults, r as genericComponent, u as propsFactory, v as convertToUnit } from "./defineComponent-D5UWd5Vb.js";
import { t as makeComponentProps } from "./component-W6F5nwNC.js";
import { t as createSimpleFunctional } from "./createSimpleFunctional-DYAlCmHj.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { n as IconValue } from "./icons-czM1t0u4.js";
import { t as VIcon } from "./VIcon-DqvHH35X.js";
import { t as makeTagProps } from "./tag-CIFqtlp2.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-C1b955Ym.js";
import { n as useDimension, t as makeDimensionProps } from "./dimensions-DYqEoPdw.js";
import { n as useLocation, t as makeLocationProps } from "./location-DD-AfEFw.js";
import { n as useRounded, t as makeRoundedProps } from "./rounded-m6mNMWh4.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-C3Dl0By9.js";
import { t as VImg } from "./VImg-D29ak-Ji.js";
import { n as useBorder, t as makeBorderProps } from "./border-DgwbzrV0.js";
import { n as useDensity, t as makeDensityProps } from "./density-Dey2iIaF.js";
import { n as makeVariantProps, r as useVariant, t as genOverlays } from "./variant-BcdnKFgE.js";
import { t as VAvatar } from "./VAvatar-BHEBKXii.js";
import { r as useLink, t as makeRouterProps } from "./router-CiYG9tKT.js";
import { n as useElevation, t as makeElevationProps } from "./elevation-DF9Lgrr_.js";
import { t as Ripple } from "./ripple-Q8q1hNUv.js";
import { n as makeLoaderProps, r as useLoader, t as LoaderSlot } from "./loader-Dn_UJdiG.js";
import { n as usePosition, t as makePositionProps } from "./position-7CDSPI1P.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VCard/VCard.css";
//#region node_modules/vuetify/lib/components/VCard/VCardActions.js
var makeVCardActionsProps = propsFactory({
+1 -1
View File
@@ -1,4 +1,4 @@
import { t as createSimpleFunctional } from "./createSimpleFunctional-CJfT4avK.js";
import { t as createSimpleFunctional } from "./createSimpleFunctional-DYAlCmHj.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VCode/VCode.css";
//#region node_modules/vuetify/lib/components/VCode/index.js
var VCode = createSimpleFunctional("v-code", "code");
+8 -8
View File
@@ -1,12 +1,12 @@
import { Dt as mergeProps, Kn as ref, Ot as nextTick, et as createVNode, gn as watch } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { K as omit, r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { n as makeVOverlayProps, t as VOverlay } from "./VOverlay-CXGz5s5q.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { t as useProxiedModel } from "./proxiedModel-BI_mmSsi.js";
import { _ as VDialogTransition } from "./transitions-CIB99T2D.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-CTN39wwv.js";
import { t as useScopeId } from "./scopeId-BhBMGBSS.js";
import { t as forwardRefs } from "./forwardRefs-BgbYSFg3.js";
import { q as omit, r as genericComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { n as makeVOverlayProps, t as VOverlay } from "./VOverlay-BntBXXGT.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { t as useProxiedModel } from "./proxiedModel-BOZtsMxA.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-C3Dl0By9.js";
import { _ as VDialogTransition } from "./transitions-llwxsiay.js";
import { t as useScopeId } from "./scopeId-BbFYJclW.js";
import { t as forwardRefs } from "./forwardRefs-C50LZ3ti.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VDialog/VDialog.css";
//#region node_modules/vuetify/lib/components/VDialog/VDialog.js
var makeVDialogProps = propsFactory({
+1 -1
View File
@@ -1,2 +1,2 @@
import { t as VDivider } from "./VDivider-vMskEUvN.js";
import { t as VDivider } from "./VDivider-Bm22Quav.js";
export { VDivider };
+16 -16
View File
@@ -1,20 +1,20 @@
import { C as vShow, Cn as withDirectives, Qn as toRef, U as computed, Ut as provide, W as createBaseVNode, ar as normalizeClass, et as createVNode, sr as normalizeStyle, xt as inject } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { X as pick, o as provideDefaults, r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as makeComponentProps } from "./component-cNt7KGbA.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-CwW_z-RC.js";
import { t as makeTagProps } from "./tag-BzACG_PL.js";
import { i as VExpandTransition } from "./transitions-CIB99T2D.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-CTN39wwv.js";
import { n as useDimension, t as makeDimensionProps } from "./dimensions-BOUfezru.js";
import { t as useBackgroundColor } from "./color-CsNXUJXB.js";
import { n as useRounded, t as makeRoundedProps } from "./rounded-zeYjdF6x.js";
import { n as useElevation, t as makeElevationProps } from "./elevation-B2sqdJV6.js";
import { i as useGroupItem, n as makeGroupProps, r as useGroup, t as makeGroupItemProps } from "./group-Ba02qEMS.js";
import { n as IconValue } from "./icons-BqOQHwEN.js";
import { t as VIcon } from "./VIcon-sEJi0XKP.js";
import { t as Ripple } from "./ripple-BcjS5Kg8.js";
import { n as useLazy, t as makeLazyProps } from "./lazy-CNRMZBuk.js";
import { Z as pick, o as provideDefaults, r as genericComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { t as makeComponentProps } from "./component-W6F5nwNC.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { t as useBackgroundColor } from "./color-B0NTWdor.js";
import { n as IconValue } from "./icons-czM1t0u4.js";
import { t as VIcon } from "./VIcon-DqvHH35X.js";
import { t as makeTagProps } from "./tag-CIFqtlp2.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-C1b955Ym.js";
import { n as useDimension, t as makeDimensionProps } from "./dimensions-DYqEoPdw.js";
import { n as useRounded, t as makeRoundedProps } from "./rounded-m6mNMWh4.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-C3Dl0By9.js";
import { i as VExpandTransition } from "./transitions-llwxsiay.js";
import { n as useLazy, t as makeLazyProps } from "./lazy-CSlNPYYk.js";
import { n as useElevation, t as makeElevationProps } from "./elevation-DF9Lgrr_.js";
import { t as Ripple } from "./ripple-Q8q1hNUv.js";
import { i as useGroupItem, n as makeGroupProps, r as useGroup, t as makeGroupItemProps } from "./group-sYL2sZpA.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VExpansionPanel/VExpansionPanel.css";
//#region node_modules/vuetify/lib/components/VExpansionPanel/shared.js
var VExpansionPanelSymbol = Symbol.for("vuetify:v-expansion-panel");
+1 -1
View File
@@ -1,2 +1,2 @@
import { i as VContainer, n as VRow, r as VCol, t as VSpacer } from "./VGrid-DPxB4khS.js";
import { i as VContainer, n as VRow, r as VCol, t as VSpacer } from "./VGrid-xu6tptBP.js";
export { VCol, VContainer, VRow, VSpacer };
+2 -2
View File
@@ -1,3 +1,3 @@
import { a as VLigatureIcon, i as VComponentIcon, o as VSvgIcon, r as VClassIcon } from "./icons-BqOQHwEN.js";
import { t as VIcon } from "./VIcon-sEJi0XKP.js";
import { a as VLigatureIcon, i as VComponentIcon, o as VSvgIcon, r as VClassIcon } from "./icons-czM1t0u4.js";
import { t as VIcon } from "./VIcon-DqvHH35X.js";
export { VClassIcon, VComponentIcon, VIcon, VLigatureIcon, VSvgIcon };
+1 -1
View File
@@ -1,2 +1,2 @@
import { t as VImg } from "./VImg-B3K_zKHG.js";
import { t as VImg } from "./VImg-D29ak-Ji.js";
export { VImg };
+1 -1
View File
@@ -1,2 +1,2 @@
import { c as VListItem, d as VListGroup, i as VList, l as VListItemTitle, n as VListItemAction, r as VListImg, s as VListSubheader, t as VListItemMedia, u as VListItemSubtitle } from "./VList-BPYFsjU7.js";
import { c as VListItem, d as VListGroup, i as VList, l as VListItemTitle, n as VListItemAction, r as VListImg, s as VListSubheader, t as VListItemMedia, u as VListItemSubtitle } from "./VList-BhbWLtAc.js";
export { VList, VListGroup, VListImg, VListItem, VListItemAction, VListItemMedia, VListItemSubtitle, VListItemTitle, VListSubheader };
+7 -7
View File
@@ -1,11 +1,11 @@
import { W as createBaseVNode, ar as normalizeClass, et as createVNode, sr as normalizeStyle } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as makeComponentProps } from "./component-cNt7KGbA.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { a as useLayout } from "./layout-Booh7E97.js";
import { t as makeTagProps } from "./tag-BzACG_PL.js";
import { n as useDimension, t as makeDimensionProps } from "./dimensions-BOUfezru.js";
import { t as useSsrBoot } from "./ssrBoot-DPOmvdPm.js";
import { r as genericComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { t as makeComponentProps } from "./component-W6F5nwNC.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { t as makeTagProps } from "./tag-CIFqtlp2.js";
import { n as useDimension, t as makeDimensionProps } from "./dimensions-DYqEoPdw.js";
import { a as useLayout } from "./layout-DcSzssSI.js";
import { t as useSsrBoot } from "./ssrBoot-Dt2Wz9ZC.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VMain/VMain.css";
//#region node_modules/vuetify/lib/components/VMain/VMain.js
var makeVMainProps = propsFactory({
+1 -1
View File
@@ -1,2 +1,2 @@
import { t as VMenu } from "./VMenu-tK8Rb46Q.js";
import { t as VMenu } from "./VMenu-g8bPIWQQ.js";
export { VMenu };
+20 -20
View File
@@ -1,24 +1,24 @@
import { Dt as mergeProps, Ft as onMounted, Gn as readonly, Kn as ref, M as Fragment, Ot as nextTick, Qn as toRef, U as computed, Vn as onScopeDispose, W as createBaseVNode, Yn as shallowRef, _n as watchEffect, et as createVNode, gn as watch, jt as onBeforeUnmount, n as Transition } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { K as omit, _ as convertToUnit, g as clamp, o as provideDefaults, r as genericComponent, u as CircularBuffer, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as makeComponentProps } from "./component-cNt7KGbA.js";
import { o as toPhysical } from "./anchor-fmhqx-jH.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { o as useLayoutItem, r as makeLayoutItemProps } from "./layout-Booh7E97.js";
import { n as useToggleScope, t as useProxiedModel } from "./proxiedModel-BI_mmSsi.js";
import { i as useRtl } from "./locale-BI-ulWIe.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-CwW_z-RC.js";
import { t as makeTagProps } from "./tag-BzACG_PL.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-CTN39wwv.js";
import { t as VImg } from "./VImg-B3K_zKHG.js";
import { t as useBackgroundColor } from "./color-CsNXUJXB.js";
import { n as useRounded, t as makeRoundedProps } from "./rounded-zeYjdF6x.js";
import { n as useBorder, t as makeBorderProps } from "./border-BomwBLze.js";
import { n as useElevation, t as makeElevationProps } from "./elevation-B2sqdJV6.js";
import { t as useSsrBoot } from "./ssrBoot-DPOmvdPm.js";
import { i as useRouter } from "./router-CXIrojRO.js";
import { a as useDisplay, i as makeDisplayProps } from "./display-NNQAdN_b.js";
import { i as useDelay, n as useFocusTrap, r as makeDelayProps, t as makeFocusTrapProps } from "./focusTrap-5P1D0YbH.js";
import { t as useScopeId } from "./scopeId-BhBMGBSS.js";
import { _ as clamp, d as CircularBuffer, o as provideDefaults, q as omit, r as genericComponent, u as propsFactory, v as convertToUnit } from "./defineComponent-D5UWd5Vb.js";
import { o as toPhysical } from "./anchor-Co261iQQ.js";
import { t as makeComponentProps } from "./component-W6F5nwNC.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { t as useBackgroundColor } from "./color-B0NTWdor.js";
import { t as makeTagProps } from "./tag-CIFqtlp2.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-C1b955Ym.js";
import { n as useToggleScope, t as useProxiedModel } from "./proxiedModel-BOZtsMxA.js";
import { i as useRtl } from "./locale-DTRSr4yu.js";
import { n as useRounded, t as makeRoundedProps } from "./rounded-m6mNMWh4.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-C3Dl0By9.js";
import { t as VImg } from "./VImg-D29ak-Ji.js";
import { n as useBorder, t as makeBorderProps } from "./border-DgwbzrV0.js";
import { o as useLayoutItem, r as makeLayoutItemProps } from "./layout-DcSzssSI.js";
import { i as useDelay, n as useFocusTrap, r as makeDelayProps, t as makeFocusTrapProps } from "./focusTrap-BRlT3Jgx.js";
import { a as useDisplay, i as makeDisplayProps } from "./display-BD8QD-8J.js";
import { i as useRouter } from "./router-CiYG9tKT.js";
import { t as useScopeId } from "./scopeId-BbFYJclW.js";
import { t as useSsrBoot } from "./ssrBoot-Dt2Wz9ZC.js";
import { n as useElevation, t as makeElevationProps } from "./elevation-DF9Lgrr_.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VNavigationDrawer/VNavigationDrawer.css";
//#region node_modules/vuetify/lib/components/VNavigationDrawer/sticky.js
function useSticky({ rootEl, isSticky, layoutItemStyles }) {
+1 -1
View File
@@ -1,2 +1,2 @@
import { t as VSelect } from "./VSelect-DP-1aJrD.js";
import { t as VSelect } from "./VSelect-9P7g-lSZ.js";
export { VSelect };
+1 -1
View File
@@ -1,2 +1,2 @@
import { t as VSheet } from "./VSheet-C9a054Bu.js";
import { t as VSheet } from "./VSheet-CdUUbWcK.js";
export { VSheet };
+11 -11
View File
@@ -1,15 +1,15 @@
import { Dt as mergeProps, Kn as ref, M as Fragment, Qn as toRef, W as createBaseVNode, ar as normalizeClass, cn as useId, et as createVNode, sr as normalizeStyle } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { T as filterInputAttrs, at as SUPPORTS_MATCH_MEDIA, r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { t as useProxiedModel } from "./proxiedModel-BI_mmSsi.js";
import { c as VScaleTransition } from "./transitions-CIB99T2D.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-CTN39wwv.js";
import { t as VIcon } from "./VIcon-sEJi0XKP.js";
import { t as VProgressCircular } from "./VProgressCircular-BQ041Mfz.js";
import { r as useLoader, t as LoaderSlot } from "./loader-Cg-RQrUq.js";
import { t as forwardRefs } from "./forwardRefs-BgbYSFg3.js";
import { a as useFocus, n as VInput, r as makeVInputProps } from "./VLabel-BWVZfhvb.js";
import { n as makeVSelectionControlProps, t as VSelectionControl } from "./VSelectionControl-CPYYRZWE.js";
import { E as filterInputAttrs, ot as SUPPORTS_MATCH_MEDIA, r as genericComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { t as VIcon } from "./VIcon-DqvHH35X.js";
import { t as useProxiedModel } from "./proxiedModel-BOZtsMxA.js";
import { t as VDefaultsProvider } from "./VDefaultsProvider-C3Dl0By9.js";
import { c as VScaleTransition } from "./transitions-llwxsiay.js";
import { t as forwardRefs } from "./forwardRefs-C50LZ3ti.js";
import { t as VProgressCircular } from "./VProgressCircular-z2FRmexp.js";
import { r as useLoader, t as LoaderSlot } from "./loader-Dn_UJdiG.js";
import { a as useFocus, n as VInput, r as makeVInputProps } from "./VLabel-BK6j7Ce3.js";
import { n as makeVSelectionControlProps, t as VSelectionControl } from "./VSelectionControl-DGk6dNy-.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VSwitch/VSwitch.css";
//#region node_modules/vuetify/lib/components/VSwitch/VSwitch.js
var makeVSwitchProps = propsFactory({
+18 -18
View File
@@ -1,24 +1,24 @@
import { C as vShow, Cn as withDirectives, Dt as mergeProps, Kn as ref, M as Fragment, Ot as nextTick, Qn as toRef, U as computed, Ut as provide, W as createBaseVNode, Yn as shallowRef, ar as normalizeClass, et as createVNode, gn as watch, sr as normalizeStyle, xt as inject } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { K as omit, U as keys, X as pick, _ as convertToUnit, nt as IN_BROWSER, o as provideDefaults, r as genericComponent, rt as PREFERS_REDUCED_MOTION, ut as propsFactory, z as isObject } from "./defineComponent-92h8LsW-.js";
import { t as makeComponentProps } from "./component-cNt7KGbA.js";
import { t as animate } from "./animation-IGJS3o2f.js";
import { B as isObject, W as keys, Z as pick, it as PREFERS_REDUCED_MOTION, o as provideDefaults, q as omit, r as genericComponent, rt as IN_BROWSER, u as propsFactory, v as convertToUnit } from "./defineComponent-D5UWd5Vb.js";
import { t as animate } from "./animation-gSo9lwa6.js";
import { t as makeComponentProps } from "./component-W6F5nwNC.js";
import { i as standardEasing } from "./easing-DfcvkbkS.js";
import { t as getScrollParent } from "./getScrollParent-DuXs8SPu.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { t as useProxiedModel } from "./proxiedModel-BI_mmSsi.js";
import { i as useRtl, r as useLocale } from "./locale-BI-ulWIe.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-CwW_z-RC.js";
import { t as makeTagProps } from "./tag-BzACG_PL.js";
import { r as useTextColor, t as useBackgroundColor } from "./color-CsNXUJXB.js";
import { t as MaybeTransition } from "./transition-C2n5e2YD.js";
import { t as useSsrBoot } from "./ssrBoot-DPOmvdPm.js";
import { n as useDensity, t as makeDensityProps } from "./density-D-xugoKB.js";
import { i as useGroupItem, r as useGroup, t as makeGroupItemProps } from "./group-Ba02qEMS.js";
import { n as makeVBtnProps, t as VBtn } from "./VBtn-0bT-99qM.js";
import { n as useLazy, t as makeLazyProps } from "./lazy-CNRMZBuk.js";
import { t as useScopeId } from "./scopeId-BhBMGBSS.js";
import { t as forwardRefs } from "./forwardRefs-BgbYSFg3.js";
import { r as makeVSlideGroupProps, t as VSlideGroup } from "./VSlideGroup-CTSq2TjT.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { r as useTextColor, t as useBackgroundColor } from "./color-B0NTWdor.js";
import { t as makeTagProps } from "./tag-CIFqtlp2.js";
import { i as provideTheme, r as makeThemeProps } from "./theme-C1b955Ym.js";
import { t as useProxiedModel } from "./proxiedModel-BOZtsMxA.js";
import { i as useRtl, r as useLocale } from "./locale-DTRSr4yu.js";
import { t as MaybeTransition } from "./transition-BieT_XBo.js";
import { n as useDensity, t as makeDensityProps } from "./density-Dey2iIaF.js";
import { n as useLazy, t as makeLazyProps } from "./lazy-CSlNPYYk.js";
import { t as useScopeId } from "./scopeId-BbFYJclW.js";
import { t as forwardRefs } from "./forwardRefs-C50LZ3ti.js";
import { t as useSsrBoot } from "./ssrBoot-Dt2Wz9ZC.js";
import { i as useGroupItem, r as useGroup, t as makeGroupItemProps } from "./group-sYL2sZpA.js";
import { n as makeVBtnProps, t as VBtn } from "./VBtn-Bm4dgaEe.js";
import { r as makeVSlideGroupProps, t as VSlideGroup } from "./VSlideGroup-CVNSOV5n.js";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VTabs/VTab.css";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VTabs/VTabs.css";
import "/Users/thackmaster/Development/routie2/frontend/node_modules/vuetify/lib/components/VWindow/VWindow.css";
+5 -5
View File
@@ -1,9 +1,9 @@
import { Qn as toRef, W as createBaseVNode, ar as normalizeClass, sr as normalizeStyle } from "./vue.runtime.esm-bundler-BvoXUmaf.js";
import { o as provideDefaults, r as genericComponent, ut as propsFactory } from "./defineComponent-92h8LsW-.js";
import { t as makeComponentProps } from "./component-cNt7KGbA.js";
import { t as useRender } from "./useRender-kn3mcOTh.js";
import { r as VToolbarTitle, t as VToolbar } from "./VToolbar-CBjuzsOU.js";
import { n as makeVariantProps } from "./variant-CXhPdVre.js";
import { o as provideDefaults, r as genericComponent, u as propsFactory } from "./defineComponent-D5UWd5Vb.js";
import { t as makeComponentProps } from "./component-W6F5nwNC.js";
import { t as useRender } from "./useRender-DB_YiTtB.js";
import { n as makeVariantProps } from "./variant-BcdnKFgE.js";
import { r as VToolbarTitle, t as VToolbar } from "./VToolbar-DAPb7QHO.js";
//#region node_modules/vuetify/lib/components/VToolbar/VToolbarItems.js
var makeVToolbarItemsProps = propsFactory({
...makeComponentProps(),
+1 -1
View File
@@ -27,7 +27,7 @@ function toast(message, opts = {}) {
}
// Shorthand helpers
const success = (msg, opts = {}) => toast(msg, { color: 'success', icon: 'mdi-check-circle-outline', ...opts })
const success = (msg, opts = {}) => toast(msg, { color: 'blue-grey', icon: 'mdi-check-circle-outline', ...opts })
const error = (msg, opts = {}) => toast(msg, { color: 'error', icon: 'mdi-alert-circle-outline', ...opts })
const warning = (msg, opts = {}) => toast(msg, { color: 'warning', icon: 'mdi-alert-outline', ...opts })
const info = (msg, opts = {}) => toast(msg, { color: 'info', icon: 'mdi-information-outline', ...opts })
-1
View File
@@ -13,7 +13,6 @@ import { VDateInput } from 'vuetify/labs/VDateInput'
export default createVuetify({
theme: {
defaultTheme: 'system',
utilities: false,
},
components: {
VDateInput,
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../jiti/lib/jiti-cli.mjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rolldown/bin/cli.mjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite/bin/vite.js
+558
View File
@@ -0,0 +1,558 @@
{
"name": "routie2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/@emnapi/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/wasi-threads": "1.2.1",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/wasi-threads": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/remapping": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.31",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@napi-rs/wasm-runtime": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
"license": "MIT",
"optional": true,
"dependencies": {
"@tybys/wasm-util": "^0.10.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
},
"peerDependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1"
}
},
"node_modules/@oxc-project/types": {
"version": "0.127.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz",
"integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==",
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/Boshen"
}
},
"node_modules/@rolldown/binding-darwin-arm64": {
"version": "1.0.0-rc.17",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz",
"integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"peer": true,
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-rc.17",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz",
"integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==",
"license": "MIT",
"peer": true
},
"node_modules/@tailwindcss/node": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz",
"integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.5",
"enhanced-resolve": "^5.19.0",
"jiti": "^2.6.1",
"lightningcss": "1.32.0",
"magic-string": "^0.30.21",
"source-map-js": "^1.2.1",
"tailwindcss": "4.2.4"
}
},
"node_modules/@tailwindcss/oxide": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz",
"integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==",
"license": "MIT",
"engines": {
"node": ">= 20"
},
"optionalDependencies": {
"@tailwindcss/oxide-android-arm64": "4.2.4",
"@tailwindcss/oxide-darwin-arm64": "4.2.4",
"@tailwindcss/oxide-darwin-x64": "4.2.4",
"@tailwindcss/oxide-freebsd-x64": "4.2.4",
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4",
"@tailwindcss/oxide-linux-arm64-gnu": "4.2.4",
"@tailwindcss/oxide-linux-arm64-musl": "4.2.4",
"@tailwindcss/oxide-linux-x64-gnu": "4.2.4",
"@tailwindcss/oxide-linux-x64-musl": "4.2.4",
"@tailwindcss/oxide-wasm32-wasi": "4.2.4",
"@tailwindcss/oxide-win32-arm64-msvc": "4.2.4",
"@tailwindcss/oxide-win32-x64-msvc": "4.2.4"
}
},
"node_modules/@tailwindcss/oxide-darwin-arm64": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.4.tgz",
"integrity": "sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 20"
}
},
"node_modules/@tailwindcss/vite": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.4.tgz",
"integrity": "sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==",
"license": "MIT",
"dependencies": {
"@tailwindcss/node": "4.2.4",
"@tailwindcss/oxide": "4.2.4",
"tailwindcss": "4.2.4"
},
"peerDependencies": {
"vite": "^5.2.0 || ^6 || ^7 || ^8"
}
},
"node_modules/@tybys/wasm-util": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/enhanced-resolve": {
"version": "5.21.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz",
"integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.3.3"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
"node_modules/jiti": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
"license": "MIT",
"bin": {
"jiti": "lib/jiti-cli.mjs"
}
},
"node_modules/lightningcss": {
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
"license": "MPL-2.0",
"dependencies": {
"detect-libc": "^2.0.3"
},
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"lightningcss-android-arm64": "1.32.0",
"lightningcss-darwin-arm64": "1.32.0",
"lightningcss-darwin-x64": "1.32.0",
"lightningcss-freebsd-x64": "1.32.0",
"lightningcss-linux-arm-gnueabihf": "1.32.0",
"lightningcss-linux-arm64-gnu": "1.32.0",
"lightningcss-linux-arm64-musl": "1.32.0",
"lightningcss-linux-x64-gnu": "1.32.0",
"lightningcss-linux-x64-musl": "1.32.0",
"lightningcss-win32-arm64-msvc": "1.32.0",
"lightningcss-win32-x64-msvc": "1.32.0"
}
},
"node_modules/lightningcss-darwin-arm64": {
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
"cpu": [
"arm64"
],
"license": "MPL-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/nanoid": {
"version": "3.3.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC",
"peer": true
},
"node_modules/picomatch": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/postcss": {
"version": "8.5.13",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.13.tgz",
"integrity": "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/rolldown": {
"version": "1.0.0-rc.17",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz",
"integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@oxc-project/types": "=0.127.0",
"@rolldown/pluginutils": "1.0.0-rc.17"
},
"bin": {
"rolldown": "bin/cli.mjs"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
"@rolldown/binding-android-arm64": "1.0.0-rc.17",
"@rolldown/binding-darwin-arm64": "1.0.0-rc.17",
"@rolldown/binding-darwin-x64": "1.0.0-rc.17",
"@rolldown/binding-freebsd-x64": "1.0.0-rc.17",
"@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17",
"@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17",
"@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17",
"@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17",
"@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17",
"@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17",
"@rolldown/binding-linux-x64-musl": "1.0.0-rc.17",
"@rolldown/binding-openharmony-arm64": "1.0.0-rc.17",
"@rolldown/binding-wasm32-wasi": "1.0.0-rc.17",
"@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17",
"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tailwindcss": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz",
"integrity": "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==",
"license": "MIT"
},
"node_modules/tapable": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",
"integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
"license": "MIT",
"engines": {
"node": ">=6"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/tinyglobby": {
"version": "0.2.16",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
"license": "MIT",
"peer": true,
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.4"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD",
"optional": true
},
"node_modules/vite": {
"version": "8.0.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz",
"integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==",
"license": "MIT",
"peer": true,
"dependencies": {
"lightningcss": "^1.32.0",
"picomatch": "^4.0.4",
"postcss": "^8.5.10",
"rolldown": "1.0.0-rc.17",
"tinyglobby": "^0.2.16"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
},
"peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0",
"@vitejs/devtools": "^0.1.0",
"esbuild": "^0.27.0 || ^0.28.0",
"jiti": ">=1.21.0",
"less": "^4.0.0",
"sass": "^1.70.0",
"sass-embedded": "^1.70.0",
"stylus": ">=0.54.8",
"sugarss": "^5.0.0",
"terser": "^5.16.0",
"tsx": "^4.8.1",
"yaml": "^2.4.2"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"@vitejs/devtools": {
"optional": true
},
"esbuild": {
"optional": true
},
"jiti": {
"optional": true
},
"less": {
"optional": true
},
"sass": {
"optional": true
},
"sass-embedded": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
},
"tsx": {
"optional": true
},
"yaml": {
"optional": true
}
}
}
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-present Toyobayashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1
View File
@@ -0,0 +1 @@
See [https://github.com/toyobayashi/emnapi](https://github.com/toyobayashi/emnapi)
+7397
View File
File diff suppressed because it is too large Load Diff
+420
View File
@@ -0,0 +1,420 @@
/// <reference types="node" />
import type { Context } from '@emnapi/runtime';
import type { ReferenceOwnership } from '@emnapi/runtime';
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare type BaseCreateOptions = {
filename?: string
nodeBinding?: NodeBinding
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
asyncWorkPoolSize?: number
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
onCreateWorker?: (info: CreateWorkerInfo) => any
print?: (str: string) => void
printErr?: (str: string) => void
postMessage?: (msg: any) => any
}
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function createNapiModule (
options: CreateOptions
): NapiModule
/** @public */
export declare type CreateOptions = BaseCreateOptions & ({
context: Context
childThread?: boolean
} | {
context?: Context
childThread: true
})
/** @public */
export declare interface CreateWorkerInfo {
type: 'thread' | 'async-work'
name: string
}
/** @public */
export declare interface InitOptions {
instance: WebAssembly.Instance
module: WebAssembly.Module
memory?: WebAssembly.Memory
table?: WebAssembly.Table
}
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
/** @public */
export declare interface InstantiatedSource extends LoadedSource {
napiModule: NapiModule;
}
/** @public */
export declare function instantiateNapiModule(
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
/** @public */
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
/** @public */
export declare type InstantiateOptions = CreateOptions & LoadOptions;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
usedInstance: WebAssembly.Instance;
}
/** @public */
export declare function loadNapiModule(napiModule: NapiModule,
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
/** @public */
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
/** @public */
export declare interface LoadOptions {
wasi?: WASIInstance;
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare class MessageHandler extends ThreadMessageHandler {
napiModule: NapiModule | undefined;
constructor(options: MessageHandlerOptions);
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
handle(e: WorkerMessageEvent): void;
}
/** @public */
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
}
/** @public */
export declare interface NapiModule {
imports: {
env: any
napi: any
emnapi: any
}
exports: any
loaded: boolean
filename: string
childThread: boolean
emnapi: {
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
js_to_wasm: boolean,
arrayBufferOrView: T,
offset?: number,
len?: number
): T
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
addSendListener (worker: any): boolean
}
init (options: InitOptions): any
initWorker (arg: number, func: [number, number]): void
postMessage?: (msg: any) => any
waitThreadStart: boolean | number
/* Excluded from this release type: PThread */}
/** @public */
export declare interface NodeBinding {
node: {
emitAsyncInit: Function
emitAsyncDestroy: Function
makeCallback: Function
}
napi: {
asyncInit: Function
asyncDestroy: Function
makeCallback: Function
}
}
/** @public */
export declare interface PointerInfo {
address: number
ownership: ReferenceOwnership
runtimeAllocated: 0 | 1
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
export declare const version: string;
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
File diff suppressed because one or more lines are too long
+420
View File
@@ -0,0 +1,420 @@
/// <reference types="node" />
import type { Context } from '@emnapi/runtime';
import type { ReferenceOwnership } from '@emnapi/runtime';
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare type BaseCreateOptions = {
filename?: string
nodeBinding?: NodeBinding
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
asyncWorkPoolSize?: number
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
onCreateWorker?: (info: CreateWorkerInfo) => any
print?: (str: string) => void
printErr?: (str: string) => void
postMessage?: (msg: any) => any
}
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function createNapiModule (
options: CreateOptions
): NapiModule
/** @public */
export declare type CreateOptions = BaseCreateOptions & ({
context: Context
childThread?: boolean
} | {
context?: Context
childThread: true
})
/** @public */
export declare interface CreateWorkerInfo {
type: 'thread' | 'async-work'
name: string
}
/** @public */
export declare interface InitOptions {
instance: WebAssembly.Instance
module: WebAssembly.Module
memory?: WebAssembly.Memory
table?: WebAssembly.Table
}
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
/** @public */
export declare interface InstantiatedSource extends LoadedSource {
napiModule: NapiModule;
}
/** @public */
export declare function instantiateNapiModule(
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
/** @public */
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
/** @public */
export declare type InstantiateOptions = CreateOptions & LoadOptions;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
usedInstance: WebAssembly.Instance;
}
/** @public */
export declare function loadNapiModule(napiModule: NapiModule,
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
/** @public */
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
/** @public */
export declare interface LoadOptions {
wasi?: WASIInstance;
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare class MessageHandler extends ThreadMessageHandler {
napiModule: NapiModule | undefined;
constructor(options: MessageHandlerOptions);
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
handle(e: WorkerMessageEvent): void;
}
/** @public */
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
}
/** @public */
export declare interface NapiModule {
imports: {
env: any
napi: any
emnapi: any
}
exports: any
loaded: boolean
filename: string
childThread: boolean
emnapi: {
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
js_to_wasm: boolean,
arrayBufferOrView: T,
offset?: number,
len?: number
): T
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
addSendListener (worker: any): boolean
}
init (options: InitOptions): any
initWorker (arg: number, func: [number, number]): void
postMessage?: (msg: any) => any
waitThreadStart: boolean | number
/* Excluded from this release type: PThread */}
/** @public */
export declare interface NodeBinding {
node: {
emitAsyncInit: Function
emitAsyncDestroy: Function
makeCallback: Function
}
napi: {
asyncInit: Function
asyncDestroy: Function
makeCallback: Function
}
}
/** @public */
export declare interface PointerInfo {
address: number
ownership: ReferenceOwnership
runtimeAllocated: 0 | 1
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
export declare const version: string;
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
+422
View File
@@ -0,0 +1,422 @@
/// <reference types="node" />
import type { Context } from '@emnapi/runtime';
import type { ReferenceOwnership } from '@emnapi/runtime';
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare type BaseCreateOptions = {
filename?: string
nodeBinding?: NodeBinding
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
asyncWorkPoolSize?: number
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
onCreateWorker?: (info: CreateWorkerInfo) => any
print?: (str: string) => void
printErr?: (str: string) => void
postMessage?: (msg: any) => any
}
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function createNapiModule (
options: CreateOptions
): NapiModule
/** @public */
export declare type CreateOptions = BaseCreateOptions & ({
context: Context
childThread?: boolean
} | {
context?: Context
childThread: true
})
/** @public */
export declare interface CreateWorkerInfo {
type: 'thread' | 'async-work'
name: string
}
/** @public */
export declare interface InitOptions {
instance: WebAssembly.Instance
module: WebAssembly.Module
memory?: WebAssembly.Memory
table?: WebAssembly.Table
}
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
/** @public */
export declare interface InstantiatedSource extends LoadedSource {
napiModule: NapiModule;
}
/** @public */
export declare function instantiateNapiModule(
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
/** @public */
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
/** @public */
export declare type InstantiateOptions = CreateOptions & LoadOptions;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
usedInstance: WebAssembly.Instance;
}
/** @public */
export declare function loadNapiModule(napiModule: NapiModule,
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
/** @public */
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
/** @public */
export declare interface LoadOptions {
wasi?: WASIInstance;
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare class MessageHandler extends ThreadMessageHandler {
napiModule: NapiModule | undefined;
constructor(options: MessageHandlerOptions);
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
handle(e: WorkerMessageEvent): void;
}
/** @public */
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
}
/** @public */
export declare interface NapiModule {
imports: {
env: any
napi: any
emnapi: any
}
exports: any
loaded: boolean
filename: string
childThread: boolean
emnapi: {
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
js_to_wasm: boolean,
arrayBufferOrView: T,
offset?: number,
len?: number
): T
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
addSendListener (worker: any): boolean
}
init (options: InitOptions): any
initWorker (arg: number, func: [number, number]): void
postMessage?: (msg: any) => any
waitThreadStart: boolean | number
/* Excluded from this release type: PThread */}
/** @public */
export declare interface NodeBinding {
node: {
emitAsyncInit: Function
emitAsyncDestroy: Function
makeCallback: Function
}
napi: {
asyncInit: Function
asyncDestroy: Function
makeCallback: Function
}
}
/** @public */
export declare interface PointerInfo {
address: number
ownership: ReferenceOwnership
runtimeAllocated: 0 | 1
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
export declare const version: string;
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
export as namespace emnapiCore;
File diff suppressed because it is too large Load Diff
+9231
View File
File diff suppressed because it is too large Load Diff
+420
View File
@@ -0,0 +1,420 @@
/// <reference types="node" />
import type { Context } from '@emnapi/runtime';
import type { ReferenceOwnership } from '@emnapi/runtime';
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare type BaseCreateOptions = {
filename?: string
nodeBinding?: NodeBinding
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
asyncWorkPoolSize?: number
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
onCreateWorker?: (info: CreateWorkerInfo) => any
print?: (str: string) => void
printErr?: (str: string) => void
postMessage?: (msg: any) => any
}
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function createNapiModule (
options: CreateOptions
): NapiModule
/** @public */
export declare type CreateOptions = BaseCreateOptions & ({
context: Context
childThread?: boolean
} | {
context?: Context
childThread: true
})
/** @public */
export declare interface CreateWorkerInfo {
type: 'thread' | 'async-work'
name: string
}
/** @public */
export declare interface InitOptions {
instance: WebAssembly.Instance
module: WebAssembly.Module
memory?: WebAssembly.Memory
table?: WebAssembly.Table
}
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
/** @public */
export declare interface InstantiatedSource extends LoadedSource {
napiModule: NapiModule;
}
/** @public */
export declare function instantiateNapiModule(
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
/** @public */
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
/** @public */
export declare type InstantiateOptions = CreateOptions & LoadOptions;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
usedInstance: WebAssembly.Instance;
}
/** @public */
export declare function loadNapiModule(napiModule: NapiModule,
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
/** @public */
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
/** @public */
export declare interface LoadOptions {
wasi?: WASIInstance;
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare class MessageHandler extends ThreadMessageHandler {
napiModule: NapiModule | undefined;
constructor(options: MessageHandlerOptions);
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
handle(e: WorkerMessageEvent): void;
}
/** @public */
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
}
/** @public */
export declare interface NapiModule {
imports: {
env: any
napi: any
emnapi: any
}
exports: any
loaded: boolean
filename: string
childThread: boolean
emnapi: {
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
js_to_wasm: boolean,
arrayBufferOrView: T,
offset?: number,
len?: number
): T
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
addSendListener (worker: any): boolean
}
init (options: InitOptions): any
initWorker (arg: number, func: [number, number]): void
postMessage?: (msg: any) => any
waitThreadStart: boolean | number
/* Excluded from this release type: PThread */}
/** @public */
export declare interface NodeBinding {
node: {
emitAsyncInit: Function
emitAsyncDestroy: Function
makeCallback: Function
}
napi: {
asyncInit: Function
asyncDestroy: Function
makeCallback: Function
}
}
/** @public */
export declare interface PointerInfo {
address: number
ownership: ReferenceOwnership
runtimeAllocated: 0 | 1
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
export declare const version: string;
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7386
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production') {
module.exports = require('./dist/emnapi-core.cjs.min.js')
} else {
module.exports = require('./dist/emnapi-core.cjs.js')
}
+49
View File
@@ -0,0 +1,49 @@
{
"name": "@emnapi/core",
"version": "1.10.0",
"description": "emnapi core",
"main": "index.js",
"module": "./dist/emnapi-core.esm-bundler.js",
"types": "./dist/emnapi-core.d.ts",
"sideEffects": false,
"exports": {
".": {
"types": {
"module": "./dist/emnapi-core.d.ts",
"import": "./dist/emnapi-core.d.mts",
"default": "./dist/emnapi-core.d.ts"
},
"module": "./dist/emnapi-core.esm-bundler.js",
"import": "./dist/emnapi-core.mjs",
"default": "./index.js"
},
"./dist/emnapi-core.cjs.min": {
"types": "./dist/emnapi-core.d.ts",
"default": "./dist/emnapi-core.cjs.min.js"
},
"./dist/emnapi-core.min.mjs": {
"types": "./dist/emnapi-core.d.mts",
"default": "./dist/emnapi-core.min.mjs"
}
},
"dependencies": {
"@emnapi/wasi-threads": "1.2.1",
"tslib": "^2.4.0"
},
"scripts": {
"build": "node ./script/build.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/toyobayashi/emnapi.git"
},
"author": "toyobayashi",
"license": "MIT",
"bugs": {
"url": "https://github.com/toyobayashi/emnapi/issues"
},
"homepage": "https://github.com/toyobayashi/emnapi#readme",
"publishConfig": {
"access": "public"
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-present Toyobayashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1
View File
@@ -0,0 +1 @@
See [https://github.com/toyobayashi/emnapi](https://github.com/toyobayashi/emnapi)
+1381
View File
File diff suppressed because it is too large Load Diff
+671
View File
@@ -0,0 +1,671 @@
export declare type Ptr = number | bigint
export declare interface IBuffer extends Uint8Array {}
export declare interface BufferCtor {
readonly prototype: IBuffer
/** @deprecated */
new (...args: any[]): IBuffer
from: {
(buffer: ArrayBufferLike): IBuffer
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
}
alloc: (size: number) => IBuffer
isBuffer: (obj: unknown) => obj is IBuffer
}
export declare const enum GlobalHandle {
UNDEFINED = 1,
NULL,
FALSE,
TRUE,
GLOBAL
}
export declare const enum Version {
NODE_API_SUPPORTED_VERSION_MIN = 1,
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
NODE_API_SUPPORTED_VERSION_MAX = 10,
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type Pointer<T> = number
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type PointerPointer<T> = number
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
export declare type Const<T> = T
export declare type void_p = Pointer<void>
export declare type void_pp = Pointer<void_p>
export declare type bool = number
export declare type char = number
export declare type char_p = Pointer<char>
export declare type unsigned_char = number
export declare type const_char = Const<char>
export declare type const_char_p = Pointer<const_char>
export declare type char16_t_p = number
export declare type const_char16_t_p = number
export declare type short = number
export declare type unsigned_short = number
export declare type int = number
export declare type unsigned_int = number
export declare type long = number
export declare type unsigned_long = number
export declare type long_long = bigint
export declare type unsigned_long_long = bigint
export declare type float = number
export declare type double = number
export declare type long_double = number
export declare type size_t = number
export declare type int8_t = number
export declare type uint8_t = number
export declare type int16_t = number
export declare type uint16_t = number
export declare type int32_t = number
export declare type uint32_t = number
export declare type int64_t = bigint
export declare type uint64_t = bigint
export declare type napi_env = Pointer<unknown>
export declare type napi_value = Pointer<unknown>
export declare type napi_ref = Pointer<unknown>
export declare type napi_deferred = Pointer<unknown>
export declare type napi_handle_scope = Pointer<unknown>
export declare type napi_escapable_handle_scope = Pointer<unknown>
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
export declare type napi_callback_info = Pointer<unknown>
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
export declare interface napi_extended_error_info {
error_message: const_char_p
engine_reserved: void_p
engine_error_code: uint32_t
error_code: napi_status
}
export declare interface napi_property_descriptor {
// One of utf8name or name should be NULL.
utf8name: const_char_p
name: napi_value
method: napi_callback
getter: napi_callback
setter: napi_callback
value: napi_value
/* napi_property_attributes */
attributes: number
data: void_p
}
export declare type napi_finalize = FunctionPointer<(
env: napi_env,
finalize_data: void_p,
finalize_hint: void_p
) => void>
export declare interface node_module {
nm_version: int32_t
nm_flags: uint32_t
nm_filename: Pointer<const_char>
nm_register_func: napi_addon_register_func
nm_modname: Pointer<const_char>
nm_priv: Pointer<void>
reserved: PointerPointer<void>
}
export declare interface napi_node_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
release: const_char_p
}
export declare interface emnapi_emscripten_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
}
export declare const enum napi_status {
napi_ok,
napi_invalid_arg,
napi_object_expected,
napi_string_expected,
napi_name_expected,
napi_function_expected,
napi_number_expected,
napi_boolean_expected,
napi_array_expected,
napi_generic_failure,
napi_pending_exception,
napi_cancelled,
napi_escape_called_twice,
napi_handle_scope_mismatch,
napi_callback_scope_mismatch,
napi_queue_full,
napi_closing,
napi_bigint_expected,
napi_date_expected,
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
napi_would_deadlock, // unused
napi_no_external_buffers_allowed,
napi_cannot_run_js
}
export declare const enum napi_property_attributes {
napi_default = 0,
napi_writable = 1 << 0,
napi_enumerable = 1 << 1,
napi_configurable = 1 << 2,
// Used with napi_define_class to distinguish static properties
// from instance properties. Ignored by napi_define_properties.
napi_static = 1 << 10,
/// #ifdef NAPI_EXPERIMENTAL
// Default for class methods.
napi_default_method = napi_writable | napi_configurable,
// Default for object properties, like in JS obj[prop].
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
/// #endif // NAPI_EXPERIMENTAL
}
export declare const enum napi_valuetype {
napi_undefined,
napi_null,
napi_boolean,
napi_number,
napi_string,
napi_symbol,
napi_object,
napi_function,
napi_external,
napi_bigint
}
export declare const enum napi_typedarray_type {
napi_int8_array,
napi_uint8_array,
napi_uint8_clamped_array,
napi_int16_array,
napi_uint16_array,
napi_int32_array,
napi_uint32_array,
napi_float32_array,
napi_float64_array,
napi_bigint64_array,
napi_biguint64_array,
napi_float16_array,
}
export declare const enum napi_key_collection_mode {
napi_key_include_prototypes,
napi_key_own_only
}
export declare const enum napi_key_filter {
napi_key_all_properties = 0,
napi_key_writable = 1,
napi_key_enumerable = 1 << 1,
napi_key_configurable = 1 << 2,
napi_key_skip_strings = 1 << 3,
napi_key_skip_symbols = 1 << 4
}
export declare const enum napi_key_conversion {
napi_key_keep_numbers,
napi_key_numbers_to_strings
}
export declare const enum emnapi_memory_view_type {
emnapi_int8_array,
emnapi_uint8_array,
emnapi_uint8_clamped_array,
emnapi_int16_array,
emnapi_uint16_array,
emnapi_int32_array,
emnapi_uint32_array,
emnapi_float32_array,
emnapi_float64_array,
emnapi_bigint64_array,
emnapi_biguint64_array,
emnapi_float16_array,
emnapi_data_view = -1,
emnapi_buffer = -2
}
export declare const enum napi_threadsafe_function_call_mode {
napi_tsfn_nonblocking,
napi_tsfn_blocking
}
export declare const enum napi_threadsafe_function_release_mode {
napi_tsfn_release,
napi_tsfn_abort
}
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
constructor(id: number, value: S);
dispose(): void;
}
export declare class Context {
private _isStopping;
private _canCallIntoJs;
private _suppressDestroy;
envStore: Store<Env>;
scopeStore: ScopeStore;
refStore: Store<Reference>;
deferredStore: Store<Deferred<any>>;
handleStore: HandleStore;
private readonly refCounter?;
private readonly cleanupQueue;
private readonly _externalMemory;
feature: {
supportReflect: boolean;
supportFinalizer: boolean;
supportWeakSymbol: boolean;
supportBigInt: boolean;
supportNewFunction: boolean;
canSetFunctionName: boolean;
setImmediate: (callback: () => void) => void;
Buffer: BufferCtor | undefined;
MessageChannel: {
new (): MessageChannel;
prototype: MessageChannel;
} | undefined;
};
constructor(options?: ContextOptions);
/**
* Suppress the destroy on `beforeExit` event in Node.js.
* Call this method if you want to keep the context and
* all associated {@link Env | Env} alive,
* this also means that cleanup hooks will not be called.
* After call this method, you should call
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
*/
suppressDestroy(): void;
getRuntimeVersions(): {
version: string;
NODE_API_SUPPORTED_VERSION_MAX: Version;
NAPI_VERSION_EXPERIMENTAL: Version;
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
};
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
getCurrentScope(): HandleScope | null;
addToCurrentScope<V>(value: V): Handle<V>;
openScope(envObject?: Env): HandleScope;
closeScope(envObject?: Env, _scope?: HandleScope): void;
ensureHandle<S>(value: S): Handle<S>;
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
runCleanup(): void;
increaseWaitingRequestCounter(): void;
decreaseWaitingRequestCounter(): void;
setCanCallIntoJs(value: boolean): void;
setStopping(value: boolean): void;
canCallIntoJs(): boolean;
/**
* Destroy the context and call cleanup hooks.
* Associated {@link Env | Env} will be destroyed.
*/
destroy(): void;
}
export declare interface ContextOptions {
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
}
export declare function createContext(options?: ContextOptions): Context;
export declare class Deferred<T = any> implements IStoreValue {
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
id: number;
ctx: Context;
value: IDeferrdValue<T>;
constructor(ctx: Context, value: IDeferrdValue<T>);
resolve(value: T): void;
reject(reason?: any): void;
dispose(): void;
}
export declare class EmnapiError extends Error {
constructor(message?: string);
}
export declare abstract class Env implements IStoreValue {
readonly ctx: Context;
moduleApiVersion: number;
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
abort: (msg?: string) => never;
id: number;
openHandleScopes: number;
instanceData: TrackedFinalizer | null;
tryCatch: TryCatch;
refs: number;
reflist: RefTracker;
finalizing_reflist: RefTracker;
pendingFinalizers: RefTracker[];
lastError: {
errorCode: napi_status;
engineErrorCode: number;
engineReserved: Ptr;
};
inGcFinalizer: boolean;
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
/** @virtual */
canCallIntoJs(): boolean;
terminatedOrTerminating(): boolean;
ref(): void;
unref(): void;
ensureHandle<S>(value: S): Handle<S>;
ensureHandleId(value: any): napi_value;
clearLastError(): napi_status;
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
getReturnStatus(): napi_status;
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
/** @virtual */
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
invokeFinalizerFromGC(finalizer: RefTracker): void;
checkGCAccess(): void;
/** @virtual */
enqueueFinalizer(finalizer: RefTracker): void;
/** @virtual */
dequeueFinalizer(finalizer: RefTracker): void;
/** @virtual */
deleteMe(): void;
dispose(): void;
private readonly _bindingMap;
initObjectBinding<S extends object>(value: S): IReferenceBinding;
getObjectBinding<S extends object>(value: S): IReferenceBinding;
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
getInstanceData(): number;
}
/** @public */
declare interface External_2 extends Record<any, any> {
}
/** @public */
declare const External_2: {
new (value: number | bigint): External_2;
prototype: null;
};
export { External_2 as External }
export declare class Finalizer {
envObject: Env;
private _finalizeCallback;
private _finalizeData;
private _finalizeHint;
private _makeDynCall_vppp;
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
callback(): napi_finalize;
data(): void_p;
hint(): void_p;
resetEnv(): void;
resetFinalizer(): void;
callFinalizer(): void;
dispose(): void;
}
export declare function getDefaultContext(): Context;
/** @public */
export declare function getExternalValue(external: External_2): number | bigint;
export declare class Handle<S> {
id: number;
value: S;
constructor(id: number, value: S);
data(): void_p;
isNumber(): boolean;
isBigInt(): boolean;
isString(): boolean;
isFunction(): boolean;
isExternal(): boolean;
isObject(): boolean;
isArray(): boolean;
isArrayBuffer(): boolean;
isTypedArray(): boolean;
isBuffer(BufferConstructor?: BufferCtor): boolean;
isDataView(): boolean;
isDate(): boolean;
isPromise(): boolean;
isBoolean(): boolean;
isUndefined(): boolean;
isSymbol(): boolean;
isNull(): boolean;
dispose(): void;
}
export declare class HandleScope {
handleStore: HandleStore;
id: number;
parent: HandleScope | null;
child: HandleScope | null;
start: number;
end: number;
private _escapeCalled;
callbackInfo: ICallbackInfo;
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
add<V>(value: V): Handle<V>;
addExternal(data: void_p): Handle<object>;
dispose(): void;
escape(handle: number): Handle<any> | null;
escapeCalled(): boolean;
}
export declare class HandleStore {
static UNDEFINED: ConstHandle<undefined>;
static NULL: ConstHandle<null>;
static FALSE: ConstHandle<false>;
static TRUE: ConstHandle<true>;
static GLOBAL: ConstHandle<typeof globalThis>;
static MIN_ID: 6;
private readonly _values;
private _next;
push<S>(value: S): Handle<S>;
erase(start: number, end: number): void;
get(id: Ptr): Handle<any> | undefined;
swap(a: number, b: number): void;
dispose(): void;
}
export declare interface ICallbackInfo {
thiz: any;
data: void_p;
args: ArrayLike<any>;
fn: Function;
}
export declare interface IDeferrdValue<T = any> {
resolve: (value: T) => void;
reject: (reason?: any) => void;
}
export declare interface IReferenceBinding {
wrapped: number;
tag: Uint32Array | null;
}
/** @public */
export declare function isExternal(object: unknown): object is External_2;
export declare function isReferenceType(v: any): v is object;
export declare interface IStoreValue {
id: number;
dispose(): void;
[x: string]: any;
}
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
export declare class NodeEnv extends Env {
filename: string;
private readonly nodeBinding?;
destructing: boolean;
finalizationScheduled: boolean;
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
deleteMe(): void;
canCallIntoJs(): boolean;
triggerFatalException(err: any): void;
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
enqueueFinalizer(finalizer: RefTracker): void;
drainFinalizerQueue(): void;
}
export declare class NotSupportBufferError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class NotSupportWeakRefError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class Persistent<T> {
private _ref;
private _param;
private _callback;
private static readonly _registry;
constructor(value: T);
setWeak<P>(param: P, callback: (param: P) => void): void;
clearWeak(): void;
reset(): void;
isEmpty(): boolean;
deref(): T | undefined;
}
export declare class Reference extends RefTracker implements IStoreValue {
private static weakCallback;
id: number;
envObject: Env;
private readonly canBeWeak;
private _refcount;
private readonly _ownership;
persistent: Persistent<object>;
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
ref(): number;
unref(): number;
get(envObject?: Env): napi_value;
/** @virtual */
resetFinalizer(): void;
/** @virtual */
data(): void_p;
refcount(): number;
ownership(): ReferenceOwnership;
/** @virtual */
protected callUserFinalizer(): void;
/** @virtual */
protected invokeFinalizerFromGC(): void;
private _setWeak;
finalize(): void;
dispose(): void;
}
export declare enum ReferenceOwnership {
kRuntime = 0,
kUserland = 1
}
export declare class ReferenceWithData extends Reference {
private readonly _data;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
private constructor();
data(): void_p;
}
export declare class ReferenceWithFinalizer extends Reference {
private _finalizer;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
private constructor();
resetFinalizer(): void;
data(): void_p;
protected callUserFinalizer(): void;
protected invokeFinalizerFromGC(): void;
dispose(): void;
}
export declare class RefTracker {
/** @virtual */
dispose(): void;
/** @virtual */
finalize(): void;
private _next;
private _prev;
link(list: RefTracker): void;
unlink(): void;
static finalizeAll(list: RefTracker): void;
}
export declare class ScopeStore {
private readonly _rootScope;
currentScope: HandleScope;
private readonly _values;
constructor();
get(id: number): HandleScope | undefined;
openScope(handleStore: HandleStore): HandleScope;
closeScope(): void;
dispose(): void;
}
export declare class Store<V extends IStoreValue> {
protected _values: Array<V | undefined>;
private _freeList;
private _size;
constructor();
add(value: V): void;
get(id: Ptr): V | undefined;
has(id: Ptr): boolean;
remove(id: Ptr): void;
dispose(): void;
}
export declare class TrackedFinalizer extends RefTracker {
private _finalizer;
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
private constructor();
data(): void_p;
dispose(): void;
finalize(): void;
}
export declare class TryCatch {
private _exception;
private _caught;
isEmpty(): boolean;
hasCaught(): boolean;
exception(): any;
setError(err: any): void;
reset(): void;
extractException(): any;
}
export declare const version: string;
export { }
File diff suppressed because one or more lines are too long
+671
View File
@@ -0,0 +1,671 @@
export declare type Ptr = number | bigint
export declare interface IBuffer extends Uint8Array {}
export declare interface BufferCtor {
readonly prototype: IBuffer
/** @deprecated */
new (...args: any[]): IBuffer
from: {
(buffer: ArrayBufferLike): IBuffer
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
}
alloc: (size: number) => IBuffer
isBuffer: (obj: unknown) => obj is IBuffer
}
export declare const enum GlobalHandle {
UNDEFINED = 1,
NULL,
FALSE,
TRUE,
GLOBAL
}
export declare const enum Version {
NODE_API_SUPPORTED_VERSION_MIN = 1,
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
NODE_API_SUPPORTED_VERSION_MAX = 10,
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type Pointer<T> = number
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type PointerPointer<T> = number
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
export declare type Const<T> = T
export declare type void_p = Pointer<void>
export declare type void_pp = Pointer<void_p>
export declare type bool = number
export declare type char = number
export declare type char_p = Pointer<char>
export declare type unsigned_char = number
export declare type const_char = Const<char>
export declare type const_char_p = Pointer<const_char>
export declare type char16_t_p = number
export declare type const_char16_t_p = number
export declare type short = number
export declare type unsigned_short = number
export declare type int = number
export declare type unsigned_int = number
export declare type long = number
export declare type unsigned_long = number
export declare type long_long = bigint
export declare type unsigned_long_long = bigint
export declare type float = number
export declare type double = number
export declare type long_double = number
export declare type size_t = number
export declare type int8_t = number
export declare type uint8_t = number
export declare type int16_t = number
export declare type uint16_t = number
export declare type int32_t = number
export declare type uint32_t = number
export declare type int64_t = bigint
export declare type uint64_t = bigint
export declare type napi_env = Pointer<unknown>
export declare type napi_value = Pointer<unknown>
export declare type napi_ref = Pointer<unknown>
export declare type napi_deferred = Pointer<unknown>
export declare type napi_handle_scope = Pointer<unknown>
export declare type napi_escapable_handle_scope = Pointer<unknown>
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
export declare type napi_callback_info = Pointer<unknown>
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
export declare interface napi_extended_error_info {
error_message: const_char_p
engine_reserved: void_p
engine_error_code: uint32_t
error_code: napi_status
}
export declare interface napi_property_descriptor {
// One of utf8name or name should be NULL.
utf8name: const_char_p
name: napi_value
method: napi_callback
getter: napi_callback
setter: napi_callback
value: napi_value
/* napi_property_attributes */
attributes: number
data: void_p
}
export declare type napi_finalize = FunctionPointer<(
env: napi_env,
finalize_data: void_p,
finalize_hint: void_p
) => void>
export declare interface node_module {
nm_version: int32_t
nm_flags: uint32_t
nm_filename: Pointer<const_char>
nm_register_func: napi_addon_register_func
nm_modname: Pointer<const_char>
nm_priv: Pointer<void>
reserved: PointerPointer<void>
}
export declare interface napi_node_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
release: const_char_p
}
export declare interface emnapi_emscripten_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
}
export declare const enum napi_status {
napi_ok,
napi_invalid_arg,
napi_object_expected,
napi_string_expected,
napi_name_expected,
napi_function_expected,
napi_number_expected,
napi_boolean_expected,
napi_array_expected,
napi_generic_failure,
napi_pending_exception,
napi_cancelled,
napi_escape_called_twice,
napi_handle_scope_mismatch,
napi_callback_scope_mismatch,
napi_queue_full,
napi_closing,
napi_bigint_expected,
napi_date_expected,
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
napi_would_deadlock, // unused
napi_no_external_buffers_allowed,
napi_cannot_run_js
}
export declare const enum napi_property_attributes {
napi_default = 0,
napi_writable = 1 << 0,
napi_enumerable = 1 << 1,
napi_configurable = 1 << 2,
// Used with napi_define_class to distinguish static properties
// from instance properties. Ignored by napi_define_properties.
napi_static = 1 << 10,
/// #ifdef NAPI_EXPERIMENTAL
// Default for class methods.
napi_default_method = napi_writable | napi_configurable,
// Default for object properties, like in JS obj[prop].
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
/// #endif // NAPI_EXPERIMENTAL
}
export declare const enum napi_valuetype {
napi_undefined,
napi_null,
napi_boolean,
napi_number,
napi_string,
napi_symbol,
napi_object,
napi_function,
napi_external,
napi_bigint
}
export declare const enum napi_typedarray_type {
napi_int8_array,
napi_uint8_array,
napi_uint8_clamped_array,
napi_int16_array,
napi_uint16_array,
napi_int32_array,
napi_uint32_array,
napi_float32_array,
napi_float64_array,
napi_bigint64_array,
napi_biguint64_array,
napi_float16_array,
}
export declare const enum napi_key_collection_mode {
napi_key_include_prototypes,
napi_key_own_only
}
export declare const enum napi_key_filter {
napi_key_all_properties = 0,
napi_key_writable = 1,
napi_key_enumerable = 1 << 1,
napi_key_configurable = 1 << 2,
napi_key_skip_strings = 1 << 3,
napi_key_skip_symbols = 1 << 4
}
export declare const enum napi_key_conversion {
napi_key_keep_numbers,
napi_key_numbers_to_strings
}
export declare const enum emnapi_memory_view_type {
emnapi_int8_array,
emnapi_uint8_array,
emnapi_uint8_clamped_array,
emnapi_int16_array,
emnapi_uint16_array,
emnapi_int32_array,
emnapi_uint32_array,
emnapi_float32_array,
emnapi_float64_array,
emnapi_bigint64_array,
emnapi_biguint64_array,
emnapi_float16_array,
emnapi_data_view = -1,
emnapi_buffer = -2
}
export declare const enum napi_threadsafe_function_call_mode {
napi_tsfn_nonblocking,
napi_tsfn_blocking
}
export declare const enum napi_threadsafe_function_release_mode {
napi_tsfn_release,
napi_tsfn_abort
}
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
constructor(id: number, value: S);
dispose(): void;
}
export declare class Context {
private _isStopping;
private _canCallIntoJs;
private _suppressDestroy;
envStore: Store<Env>;
scopeStore: ScopeStore;
refStore: Store<Reference>;
deferredStore: Store<Deferred<any>>;
handleStore: HandleStore;
private readonly refCounter?;
private readonly cleanupQueue;
private readonly _externalMemory;
feature: {
supportReflect: boolean;
supportFinalizer: boolean;
supportWeakSymbol: boolean;
supportBigInt: boolean;
supportNewFunction: boolean;
canSetFunctionName: boolean;
setImmediate: (callback: () => void) => void;
Buffer: BufferCtor | undefined;
MessageChannel: {
new (): MessageChannel;
prototype: MessageChannel;
} | undefined;
};
constructor(options?: ContextOptions);
/**
* Suppress the destroy on `beforeExit` event in Node.js.
* Call this method if you want to keep the context and
* all associated {@link Env | Env} alive,
* this also means that cleanup hooks will not be called.
* After call this method, you should call
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
*/
suppressDestroy(): void;
getRuntimeVersions(): {
version: string;
NODE_API_SUPPORTED_VERSION_MAX: Version;
NAPI_VERSION_EXPERIMENTAL: Version;
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
};
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
getCurrentScope(): HandleScope | null;
addToCurrentScope<V>(value: V): Handle<V>;
openScope(envObject?: Env): HandleScope;
closeScope(envObject?: Env, _scope?: HandleScope): void;
ensureHandle<S>(value: S): Handle<S>;
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
runCleanup(): void;
increaseWaitingRequestCounter(): void;
decreaseWaitingRequestCounter(): void;
setCanCallIntoJs(value: boolean): void;
setStopping(value: boolean): void;
canCallIntoJs(): boolean;
/**
* Destroy the context and call cleanup hooks.
* Associated {@link Env | Env} will be destroyed.
*/
destroy(): void;
}
export declare interface ContextOptions {
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
}
export declare function createContext(options?: ContextOptions): Context;
export declare class Deferred<T = any> implements IStoreValue {
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
id: number;
ctx: Context;
value: IDeferrdValue<T>;
constructor(ctx: Context, value: IDeferrdValue<T>);
resolve(value: T): void;
reject(reason?: any): void;
dispose(): void;
}
export declare class EmnapiError extends Error {
constructor(message?: string);
}
export declare abstract class Env implements IStoreValue {
readonly ctx: Context;
moduleApiVersion: number;
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
abort: (msg?: string) => never;
id: number;
openHandleScopes: number;
instanceData: TrackedFinalizer | null;
tryCatch: TryCatch;
refs: number;
reflist: RefTracker;
finalizing_reflist: RefTracker;
pendingFinalizers: RefTracker[];
lastError: {
errorCode: napi_status;
engineErrorCode: number;
engineReserved: Ptr;
};
inGcFinalizer: boolean;
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
/** @virtual */
canCallIntoJs(): boolean;
terminatedOrTerminating(): boolean;
ref(): void;
unref(): void;
ensureHandle<S>(value: S): Handle<S>;
ensureHandleId(value: any): napi_value;
clearLastError(): napi_status;
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
getReturnStatus(): napi_status;
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
/** @virtual */
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
invokeFinalizerFromGC(finalizer: RefTracker): void;
checkGCAccess(): void;
/** @virtual */
enqueueFinalizer(finalizer: RefTracker): void;
/** @virtual */
dequeueFinalizer(finalizer: RefTracker): void;
/** @virtual */
deleteMe(): void;
dispose(): void;
private readonly _bindingMap;
initObjectBinding<S extends object>(value: S): IReferenceBinding;
getObjectBinding<S extends object>(value: S): IReferenceBinding;
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
getInstanceData(): number;
}
/** @public */
declare interface External_2 extends Record<any, any> {
}
/** @public */
declare const External_2: {
new (value: number | bigint): External_2;
prototype: null;
};
export { External_2 as External }
export declare class Finalizer {
envObject: Env;
private _finalizeCallback;
private _finalizeData;
private _finalizeHint;
private _makeDynCall_vppp;
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
callback(): napi_finalize;
data(): void_p;
hint(): void_p;
resetEnv(): void;
resetFinalizer(): void;
callFinalizer(): void;
dispose(): void;
}
export declare function getDefaultContext(): Context;
/** @public */
export declare function getExternalValue(external: External_2): number | bigint;
export declare class Handle<S> {
id: number;
value: S;
constructor(id: number, value: S);
data(): void_p;
isNumber(): boolean;
isBigInt(): boolean;
isString(): boolean;
isFunction(): boolean;
isExternal(): boolean;
isObject(): boolean;
isArray(): boolean;
isArrayBuffer(): boolean;
isTypedArray(): boolean;
isBuffer(BufferConstructor?: BufferCtor): boolean;
isDataView(): boolean;
isDate(): boolean;
isPromise(): boolean;
isBoolean(): boolean;
isUndefined(): boolean;
isSymbol(): boolean;
isNull(): boolean;
dispose(): void;
}
export declare class HandleScope {
handleStore: HandleStore;
id: number;
parent: HandleScope | null;
child: HandleScope | null;
start: number;
end: number;
private _escapeCalled;
callbackInfo: ICallbackInfo;
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
add<V>(value: V): Handle<V>;
addExternal(data: void_p): Handle<object>;
dispose(): void;
escape(handle: number): Handle<any> | null;
escapeCalled(): boolean;
}
export declare class HandleStore {
static UNDEFINED: ConstHandle<undefined>;
static NULL: ConstHandle<null>;
static FALSE: ConstHandle<false>;
static TRUE: ConstHandle<true>;
static GLOBAL: ConstHandle<typeof globalThis>;
static MIN_ID: 6;
private readonly _values;
private _next;
push<S>(value: S): Handle<S>;
erase(start: number, end: number): void;
get(id: Ptr): Handle<any> | undefined;
swap(a: number, b: number): void;
dispose(): void;
}
export declare interface ICallbackInfo {
thiz: any;
data: void_p;
args: ArrayLike<any>;
fn: Function;
}
export declare interface IDeferrdValue<T = any> {
resolve: (value: T) => void;
reject: (reason?: any) => void;
}
export declare interface IReferenceBinding {
wrapped: number;
tag: Uint32Array | null;
}
/** @public */
export declare function isExternal(object: unknown): object is External_2;
export declare function isReferenceType(v: any): v is object;
export declare interface IStoreValue {
id: number;
dispose(): void;
[x: string]: any;
}
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
export declare class NodeEnv extends Env {
filename: string;
private readonly nodeBinding?;
destructing: boolean;
finalizationScheduled: boolean;
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
deleteMe(): void;
canCallIntoJs(): boolean;
triggerFatalException(err: any): void;
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
enqueueFinalizer(finalizer: RefTracker): void;
drainFinalizerQueue(): void;
}
export declare class NotSupportBufferError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class NotSupportWeakRefError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class Persistent<T> {
private _ref;
private _param;
private _callback;
private static readonly _registry;
constructor(value: T);
setWeak<P>(param: P, callback: (param: P) => void): void;
clearWeak(): void;
reset(): void;
isEmpty(): boolean;
deref(): T | undefined;
}
export declare class Reference extends RefTracker implements IStoreValue {
private static weakCallback;
id: number;
envObject: Env;
private readonly canBeWeak;
private _refcount;
private readonly _ownership;
persistent: Persistent<object>;
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
ref(): number;
unref(): number;
get(envObject?: Env): napi_value;
/** @virtual */
resetFinalizer(): void;
/** @virtual */
data(): void_p;
refcount(): number;
ownership(): ReferenceOwnership;
/** @virtual */
protected callUserFinalizer(): void;
/** @virtual */
protected invokeFinalizerFromGC(): void;
private _setWeak;
finalize(): void;
dispose(): void;
}
export declare enum ReferenceOwnership {
kRuntime = 0,
kUserland = 1
}
export declare class ReferenceWithData extends Reference {
private readonly _data;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
private constructor();
data(): void_p;
}
export declare class ReferenceWithFinalizer extends Reference {
private _finalizer;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
private constructor();
resetFinalizer(): void;
data(): void_p;
protected callUserFinalizer(): void;
protected invokeFinalizerFromGC(): void;
dispose(): void;
}
export declare class RefTracker {
/** @virtual */
dispose(): void;
/** @virtual */
finalize(): void;
private _next;
private _prev;
link(list: RefTracker): void;
unlink(): void;
static finalizeAll(list: RefTracker): void;
}
export declare class ScopeStore {
private readonly _rootScope;
currentScope: HandleScope;
private readonly _values;
constructor();
get(id: number): HandleScope | undefined;
openScope(handleStore: HandleStore): HandleScope;
closeScope(): void;
dispose(): void;
}
export declare class Store<V extends IStoreValue> {
protected _values: Array<V | undefined>;
private _freeList;
private _size;
constructor();
add(value: V): void;
get(id: Ptr): V | undefined;
has(id: Ptr): boolean;
remove(id: Ptr): void;
dispose(): void;
}
export declare class TrackedFinalizer extends RefTracker {
private _finalizer;
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
private constructor();
data(): void_p;
dispose(): void;
finalize(): void;
}
export declare class TryCatch {
private _exception;
private _caught;
isEmpty(): boolean;
hasCaught(): boolean;
exception(): any;
setError(err: any): void;
reset(): void;
extractException(): any;
}
export declare const version: string;
export { }
+673
View File
@@ -0,0 +1,673 @@
export declare type Ptr = number | bigint
export declare interface IBuffer extends Uint8Array {}
export declare interface BufferCtor {
readonly prototype: IBuffer
/** @deprecated */
new (...args: any[]): IBuffer
from: {
(buffer: ArrayBufferLike): IBuffer
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
}
alloc: (size: number) => IBuffer
isBuffer: (obj: unknown) => obj is IBuffer
}
export declare const enum GlobalHandle {
UNDEFINED = 1,
NULL,
FALSE,
TRUE,
GLOBAL
}
export declare const enum Version {
NODE_API_SUPPORTED_VERSION_MIN = 1,
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
NODE_API_SUPPORTED_VERSION_MAX = 10,
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type Pointer<T> = number
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type PointerPointer<T> = number
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
export declare type Const<T> = T
export declare type void_p = Pointer<void>
export declare type void_pp = Pointer<void_p>
export declare type bool = number
export declare type char = number
export declare type char_p = Pointer<char>
export declare type unsigned_char = number
export declare type const_char = Const<char>
export declare type const_char_p = Pointer<const_char>
export declare type char16_t_p = number
export declare type const_char16_t_p = number
export declare type short = number
export declare type unsigned_short = number
export declare type int = number
export declare type unsigned_int = number
export declare type long = number
export declare type unsigned_long = number
export declare type long_long = bigint
export declare type unsigned_long_long = bigint
export declare type float = number
export declare type double = number
export declare type long_double = number
export declare type size_t = number
export declare type int8_t = number
export declare type uint8_t = number
export declare type int16_t = number
export declare type uint16_t = number
export declare type int32_t = number
export declare type uint32_t = number
export declare type int64_t = bigint
export declare type uint64_t = bigint
export declare type napi_env = Pointer<unknown>
export declare type napi_value = Pointer<unknown>
export declare type napi_ref = Pointer<unknown>
export declare type napi_deferred = Pointer<unknown>
export declare type napi_handle_scope = Pointer<unknown>
export declare type napi_escapable_handle_scope = Pointer<unknown>
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
export declare type napi_callback_info = Pointer<unknown>
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
export declare interface napi_extended_error_info {
error_message: const_char_p
engine_reserved: void_p
engine_error_code: uint32_t
error_code: napi_status
}
export declare interface napi_property_descriptor {
// One of utf8name or name should be NULL.
utf8name: const_char_p
name: napi_value
method: napi_callback
getter: napi_callback
setter: napi_callback
value: napi_value
/* napi_property_attributes */
attributes: number
data: void_p
}
export declare type napi_finalize = FunctionPointer<(
env: napi_env,
finalize_data: void_p,
finalize_hint: void_p
) => void>
export declare interface node_module {
nm_version: int32_t
nm_flags: uint32_t
nm_filename: Pointer<const_char>
nm_register_func: napi_addon_register_func
nm_modname: Pointer<const_char>
nm_priv: Pointer<void>
reserved: PointerPointer<void>
}
export declare interface napi_node_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
release: const_char_p
}
export declare interface emnapi_emscripten_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
}
export declare const enum napi_status {
napi_ok,
napi_invalid_arg,
napi_object_expected,
napi_string_expected,
napi_name_expected,
napi_function_expected,
napi_number_expected,
napi_boolean_expected,
napi_array_expected,
napi_generic_failure,
napi_pending_exception,
napi_cancelled,
napi_escape_called_twice,
napi_handle_scope_mismatch,
napi_callback_scope_mismatch,
napi_queue_full,
napi_closing,
napi_bigint_expected,
napi_date_expected,
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
napi_would_deadlock, // unused
napi_no_external_buffers_allowed,
napi_cannot_run_js
}
export declare const enum napi_property_attributes {
napi_default = 0,
napi_writable = 1 << 0,
napi_enumerable = 1 << 1,
napi_configurable = 1 << 2,
// Used with napi_define_class to distinguish static properties
// from instance properties. Ignored by napi_define_properties.
napi_static = 1 << 10,
/// #ifdef NAPI_EXPERIMENTAL
// Default for class methods.
napi_default_method = napi_writable | napi_configurable,
// Default for object properties, like in JS obj[prop].
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
/// #endif // NAPI_EXPERIMENTAL
}
export declare const enum napi_valuetype {
napi_undefined,
napi_null,
napi_boolean,
napi_number,
napi_string,
napi_symbol,
napi_object,
napi_function,
napi_external,
napi_bigint
}
export declare const enum napi_typedarray_type {
napi_int8_array,
napi_uint8_array,
napi_uint8_clamped_array,
napi_int16_array,
napi_uint16_array,
napi_int32_array,
napi_uint32_array,
napi_float32_array,
napi_float64_array,
napi_bigint64_array,
napi_biguint64_array,
napi_float16_array,
}
export declare const enum napi_key_collection_mode {
napi_key_include_prototypes,
napi_key_own_only
}
export declare const enum napi_key_filter {
napi_key_all_properties = 0,
napi_key_writable = 1,
napi_key_enumerable = 1 << 1,
napi_key_configurable = 1 << 2,
napi_key_skip_strings = 1 << 3,
napi_key_skip_symbols = 1 << 4
}
export declare const enum napi_key_conversion {
napi_key_keep_numbers,
napi_key_numbers_to_strings
}
export declare const enum emnapi_memory_view_type {
emnapi_int8_array,
emnapi_uint8_array,
emnapi_uint8_clamped_array,
emnapi_int16_array,
emnapi_uint16_array,
emnapi_int32_array,
emnapi_uint32_array,
emnapi_float32_array,
emnapi_float64_array,
emnapi_bigint64_array,
emnapi_biguint64_array,
emnapi_float16_array,
emnapi_data_view = -1,
emnapi_buffer = -2
}
export declare const enum napi_threadsafe_function_call_mode {
napi_tsfn_nonblocking,
napi_tsfn_blocking
}
export declare const enum napi_threadsafe_function_release_mode {
napi_tsfn_release,
napi_tsfn_abort
}
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
constructor(id: number, value: S);
dispose(): void;
}
export declare class Context {
private _isStopping;
private _canCallIntoJs;
private _suppressDestroy;
envStore: Store<Env>;
scopeStore: ScopeStore;
refStore: Store<Reference>;
deferredStore: Store<Deferred<any>>;
handleStore: HandleStore;
private readonly refCounter?;
private readonly cleanupQueue;
private readonly _externalMemory;
feature: {
supportReflect: boolean;
supportFinalizer: boolean;
supportWeakSymbol: boolean;
supportBigInt: boolean;
supportNewFunction: boolean;
canSetFunctionName: boolean;
setImmediate: (callback: () => void) => void;
Buffer: BufferCtor | undefined;
MessageChannel: {
new (): MessageChannel;
prototype: MessageChannel;
} | undefined;
};
constructor(options?: ContextOptions);
/**
* Suppress the destroy on `beforeExit` event in Node.js.
* Call this method if you want to keep the context and
* all associated {@link Env | Env} alive,
* this also means that cleanup hooks will not be called.
* After call this method, you should call
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
*/
suppressDestroy(): void;
getRuntimeVersions(): {
version: string;
NODE_API_SUPPORTED_VERSION_MAX: Version;
NAPI_VERSION_EXPERIMENTAL: Version;
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
};
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
getCurrentScope(): HandleScope | null;
addToCurrentScope<V>(value: V): Handle<V>;
openScope(envObject?: Env): HandleScope;
closeScope(envObject?: Env, _scope?: HandleScope): void;
ensureHandle<S>(value: S): Handle<S>;
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
runCleanup(): void;
increaseWaitingRequestCounter(): void;
decreaseWaitingRequestCounter(): void;
setCanCallIntoJs(value: boolean): void;
setStopping(value: boolean): void;
canCallIntoJs(): boolean;
/**
* Destroy the context and call cleanup hooks.
* Associated {@link Env | Env} will be destroyed.
*/
destroy(): void;
}
export declare interface ContextOptions {
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
}
export declare function createContext(options?: ContextOptions): Context;
export declare class Deferred<T = any> implements IStoreValue {
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
id: number;
ctx: Context;
value: IDeferrdValue<T>;
constructor(ctx: Context, value: IDeferrdValue<T>);
resolve(value: T): void;
reject(reason?: any): void;
dispose(): void;
}
export declare class EmnapiError extends Error {
constructor(message?: string);
}
export declare abstract class Env implements IStoreValue {
readonly ctx: Context;
moduleApiVersion: number;
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
abort: (msg?: string) => never;
id: number;
openHandleScopes: number;
instanceData: TrackedFinalizer | null;
tryCatch: TryCatch;
refs: number;
reflist: RefTracker;
finalizing_reflist: RefTracker;
pendingFinalizers: RefTracker[];
lastError: {
errorCode: napi_status;
engineErrorCode: number;
engineReserved: Ptr;
};
inGcFinalizer: boolean;
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
/** @virtual */
canCallIntoJs(): boolean;
terminatedOrTerminating(): boolean;
ref(): void;
unref(): void;
ensureHandle<S>(value: S): Handle<S>;
ensureHandleId(value: any): napi_value;
clearLastError(): napi_status;
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
getReturnStatus(): napi_status;
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
/** @virtual */
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
invokeFinalizerFromGC(finalizer: RefTracker): void;
checkGCAccess(): void;
/** @virtual */
enqueueFinalizer(finalizer: RefTracker): void;
/** @virtual */
dequeueFinalizer(finalizer: RefTracker): void;
/** @virtual */
deleteMe(): void;
dispose(): void;
private readonly _bindingMap;
initObjectBinding<S extends object>(value: S): IReferenceBinding;
getObjectBinding<S extends object>(value: S): IReferenceBinding;
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
getInstanceData(): number;
}
/** @public */
declare interface External_2 extends Record<any, any> {
}
/** @public */
declare const External_2: {
new (value: number | bigint): External_2;
prototype: null;
};
export { External_2 as External }
export declare class Finalizer {
envObject: Env;
private _finalizeCallback;
private _finalizeData;
private _finalizeHint;
private _makeDynCall_vppp;
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
callback(): napi_finalize;
data(): void_p;
hint(): void_p;
resetEnv(): void;
resetFinalizer(): void;
callFinalizer(): void;
dispose(): void;
}
export declare function getDefaultContext(): Context;
/** @public */
export declare function getExternalValue(external: External_2): number | bigint;
export declare class Handle<S> {
id: number;
value: S;
constructor(id: number, value: S);
data(): void_p;
isNumber(): boolean;
isBigInt(): boolean;
isString(): boolean;
isFunction(): boolean;
isExternal(): boolean;
isObject(): boolean;
isArray(): boolean;
isArrayBuffer(): boolean;
isTypedArray(): boolean;
isBuffer(BufferConstructor?: BufferCtor): boolean;
isDataView(): boolean;
isDate(): boolean;
isPromise(): boolean;
isBoolean(): boolean;
isUndefined(): boolean;
isSymbol(): boolean;
isNull(): boolean;
dispose(): void;
}
export declare class HandleScope {
handleStore: HandleStore;
id: number;
parent: HandleScope | null;
child: HandleScope | null;
start: number;
end: number;
private _escapeCalled;
callbackInfo: ICallbackInfo;
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
add<V>(value: V): Handle<V>;
addExternal(data: void_p): Handle<object>;
dispose(): void;
escape(handle: number): Handle<any> | null;
escapeCalled(): boolean;
}
export declare class HandleStore {
static UNDEFINED: ConstHandle<undefined>;
static NULL: ConstHandle<null>;
static FALSE: ConstHandle<false>;
static TRUE: ConstHandle<true>;
static GLOBAL: ConstHandle<typeof globalThis>;
static MIN_ID: 6;
private readonly _values;
private _next;
push<S>(value: S): Handle<S>;
erase(start: number, end: number): void;
get(id: Ptr): Handle<any> | undefined;
swap(a: number, b: number): void;
dispose(): void;
}
export declare interface ICallbackInfo {
thiz: any;
data: void_p;
args: ArrayLike<any>;
fn: Function;
}
export declare interface IDeferrdValue<T = any> {
resolve: (value: T) => void;
reject: (reason?: any) => void;
}
export declare interface IReferenceBinding {
wrapped: number;
tag: Uint32Array | null;
}
/** @public */
export declare function isExternal(object: unknown): object is External_2;
export declare function isReferenceType(v: any): v is object;
export declare interface IStoreValue {
id: number;
dispose(): void;
[x: string]: any;
}
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
export declare class NodeEnv extends Env {
filename: string;
private readonly nodeBinding?;
destructing: boolean;
finalizationScheduled: boolean;
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
deleteMe(): void;
canCallIntoJs(): boolean;
triggerFatalException(err: any): void;
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
enqueueFinalizer(finalizer: RefTracker): void;
drainFinalizerQueue(): void;
}
export declare class NotSupportBufferError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class NotSupportWeakRefError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class Persistent<T> {
private _ref;
private _param;
private _callback;
private static readonly _registry;
constructor(value: T);
setWeak<P>(param: P, callback: (param: P) => void): void;
clearWeak(): void;
reset(): void;
isEmpty(): boolean;
deref(): T | undefined;
}
export declare class Reference extends RefTracker implements IStoreValue {
private static weakCallback;
id: number;
envObject: Env;
private readonly canBeWeak;
private _refcount;
private readonly _ownership;
persistent: Persistent<object>;
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
ref(): number;
unref(): number;
get(envObject?: Env): napi_value;
/** @virtual */
resetFinalizer(): void;
/** @virtual */
data(): void_p;
refcount(): number;
ownership(): ReferenceOwnership;
/** @virtual */
protected callUserFinalizer(): void;
/** @virtual */
protected invokeFinalizerFromGC(): void;
private _setWeak;
finalize(): void;
dispose(): void;
}
export declare enum ReferenceOwnership {
kRuntime = 0,
kUserland = 1
}
export declare class ReferenceWithData extends Reference {
private readonly _data;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
private constructor();
data(): void_p;
}
export declare class ReferenceWithFinalizer extends Reference {
private _finalizer;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
private constructor();
resetFinalizer(): void;
data(): void_p;
protected callUserFinalizer(): void;
protected invokeFinalizerFromGC(): void;
dispose(): void;
}
export declare class RefTracker {
/** @virtual */
dispose(): void;
/** @virtual */
finalize(): void;
private _next;
private _prev;
link(list: RefTracker): void;
unlink(): void;
static finalizeAll(list: RefTracker): void;
}
export declare class ScopeStore {
private readonly _rootScope;
currentScope: HandleScope;
private readonly _values;
constructor();
get(id: number): HandleScope | undefined;
openScope(handleStore: HandleStore): HandleScope;
closeScope(): void;
dispose(): void;
}
export declare class Store<V extends IStoreValue> {
protected _values: Array<V | undefined>;
private _freeList;
private _size;
constructor();
add(value: V): void;
get(id: Ptr): V | undefined;
has(id: Ptr): boolean;
remove(id: Ptr): void;
dispose(): void;
}
export declare class TrackedFinalizer extends RefTracker {
private _finalizer;
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
private constructor();
data(): void_p;
dispose(): void;
finalize(): void;
}
export declare class TryCatch {
private _exception;
private _caught;
isEmpty(): boolean;
hasCaught(): boolean;
exception(): any;
setError(err: any): void;
reset(): void;
extractException(): any;
}
export declare const version: string;
export { }
export as namespace emnapi;
File diff suppressed because it is too large Load Diff
+426
View File
@@ -0,0 +1,426 @@
declare namespace emnapi {
export type CleanupHookCallbackFunction = number | ((arg: number) => void);
export class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
constructor(id: number, value: S);
dispose(): void;
}
export class Context {
private _isStopping;
private _canCallIntoJs;
private _suppressDestroy;
envStore: Store<Env>;
scopeStore: ScopeStore;
refStore: Store<Reference>;
deferredStore: Store<Deferred<any>>;
handleStore: HandleStore;
private readonly refCounter?;
private readonly cleanupQueue;
private readonly _externalMemory;
feature: {
supportReflect: boolean;
supportFinalizer: boolean;
supportWeakSymbol: boolean;
supportBigInt: boolean;
supportNewFunction: boolean;
canSetFunctionName: boolean;
setImmediate: (callback: () => void) => void;
Buffer: BufferCtor | undefined;
MessageChannel: {
new (): MessageChannel;
prototype: MessageChannel;
} | undefined;
};
constructor(options?: ContextOptions);
/**
* Suppress the destroy on `beforeExit` event in Node.js.
* Call this method if you want to keep the context and
* all associated {@link Env | Env} alive,
* this also means that cleanup hooks will not be called.
* After call this method, you should call
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
*/
suppressDestroy(): void;
getRuntimeVersions(): {
version: string;
NODE_API_SUPPORTED_VERSION_MAX: Version;
NAPI_VERSION_EXPERIMENTAL: Version;
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
};
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
getCurrentScope(): HandleScope | null;
addToCurrentScope<V>(value: V): Handle<V>;
openScope(envObject?: Env): HandleScope;
closeScope(envObject?: Env, _scope?: HandleScope): void;
ensureHandle<S>(value: S): Handle<S>;
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
runCleanup(): void;
increaseWaitingRequestCounter(): void;
decreaseWaitingRequestCounter(): void;
setCanCallIntoJs(value: boolean): void;
setStopping(value: boolean): void;
canCallIntoJs(): boolean;
/**
* Destroy the context and call cleanup hooks.
* Associated {@link Env | Env} will be destroyed.
*/
destroy(): void;
}
export interface ContextOptions {
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
}
export function createContext(options?: ContextOptions): Context;
export class Deferred<T = any> implements IStoreValue {
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
id: number;
ctx: Context;
value: IDeferrdValue<T>;
constructor(ctx: Context, value: IDeferrdValue<T>);
resolve(value: T): void;
reject(reason?: any): void;
dispose(): void;
}
export class EmnapiError extends Error {
constructor(message?: string);
}
export abstract class Env implements IStoreValue {
readonly ctx: Context;
moduleApiVersion: number;
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
abort: (msg?: string) => never;
id: number;
openHandleScopes: number;
instanceData: TrackedFinalizer | null;
tryCatch: TryCatch;
refs: number;
reflist: RefTracker;
finalizing_reflist: RefTracker;
pendingFinalizers: RefTracker[];
lastError: {
errorCode: napi_status;
engineErrorCode: number;
engineReserved: Ptr;
};
inGcFinalizer: boolean;
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
/** @virtual */
canCallIntoJs(): boolean;
terminatedOrTerminating(): boolean;
ref(): void;
unref(): void;
ensureHandle<S>(value: S): Handle<S>;
ensureHandleId(value: any): napi_value;
clearLastError(): napi_status;
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
getReturnStatus(): napi_status;
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
/** @virtual */
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
invokeFinalizerFromGC(finalizer: RefTracker): void;
checkGCAccess(): void;
/** @virtual */
enqueueFinalizer(finalizer: RefTracker): void;
/** @virtual */
dequeueFinalizer(finalizer: RefTracker): void;
/** @virtual */
deleteMe(): void;
dispose(): void;
private readonly _bindingMap;
initObjectBinding<S extends object>(value: S): IReferenceBinding;
getObjectBinding<S extends object>(value: S): IReferenceBinding;
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
getInstanceData(): number;
}
/** @public */
interface External_2 extends Record<any, any> {
}
/** @public */
const External_2: {
new (value: number | bigint): External_2;
prototype: null;
};
export { External_2 as External }
export class Finalizer {
envObject: Env;
private _finalizeCallback;
private _finalizeData;
private _finalizeHint;
private _makeDynCall_vppp;
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
callback(): napi_finalize;
data(): void_p;
hint(): void_p;
resetEnv(): void;
resetFinalizer(): void;
callFinalizer(): void;
dispose(): void;
}
export function getDefaultContext(): Context;
/** @public */
export function getExternalValue(external: External_2): number | bigint;
export class Handle<S> {
id: number;
value: S;
constructor(id: number, value: S);
data(): void_p;
isNumber(): boolean;
isBigInt(): boolean;
isString(): boolean;
isFunction(): boolean;
isExternal(): boolean;
isObject(): boolean;
isArray(): boolean;
isArrayBuffer(): boolean;
isTypedArray(): boolean;
isBuffer(BufferConstructor?: BufferCtor): boolean;
isDataView(): boolean;
isDate(): boolean;
isPromise(): boolean;
isBoolean(): boolean;
isUndefined(): boolean;
isSymbol(): boolean;
isNull(): boolean;
dispose(): void;
}
export class HandleScope {
handleStore: HandleStore;
id: number;
parent: HandleScope | null;
child: HandleScope | null;
start: number;
end: number;
private _escapeCalled;
callbackInfo: ICallbackInfo;
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
add<V>(value: V): Handle<V>;
addExternal(data: void_p): Handle<object>;
dispose(): void;
escape(handle: number): Handle<any> | null;
escapeCalled(): boolean;
}
export class HandleStore {
static UNDEFINED: ConstHandle<undefined>;
static NULL: ConstHandle<null>;
static FALSE: ConstHandle<false>;
static TRUE: ConstHandle<true>;
static GLOBAL: ConstHandle<typeof globalThis>;
static MIN_ID: 6;
private readonly _values;
private _next;
push<S>(value: S): Handle<S>;
erase(start: number, end: number): void;
get(id: Ptr): Handle<any> | undefined;
swap(a: number, b: number): void;
dispose(): void;
}
export interface ICallbackInfo {
thiz: any;
data: void_p;
args: ArrayLike<any>;
fn: Function;
}
export interface IDeferrdValue<T = any> {
resolve: (value: T) => void;
reject: (reason?: any) => void;
}
export interface IReferenceBinding {
wrapped: number;
tag: Uint32Array | null;
}
/** @public */
export function isExternal(object: unknown): object is External_2;
export function isReferenceType(v: any): v is object;
export interface IStoreValue {
id: number;
dispose(): void;
[x: string]: any;
}
export const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
export const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
export const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
export const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
export class NodeEnv extends Env {
filename: string;
private readonly nodeBinding?;
destructing: boolean;
finalizationScheduled: boolean;
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
deleteMe(): void;
canCallIntoJs(): boolean;
triggerFatalException(err: any): void;
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
enqueueFinalizer(finalizer: RefTracker): void;
drainFinalizerQueue(): void;
}
export class NotSupportBufferError extends EmnapiError {
constructor(api: string, message: string);
}
export class NotSupportWeakRefError extends EmnapiError {
constructor(api: string, message: string);
}
export class Persistent<T> {
private _ref;
private _param;
private _callback;
private static readonly _registry;
constructor(value: T);
setWeak<P>(param: P, callback: (param: P) => void): void;
clearWeak(): void;
reset(): void;
isEmpty(): boolean;
deref(): T | undefined;
}
export class Reference extends RefTracker implements IStoreValue {
private static weakCallback;
id: number;
envObject: Env;
private readonly canBeWeak;
private _refcount;
private readonly _ownership;
persistent: Persistent<object>;
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
ref(): number;
unref(): number;
get(envObject?: Env): napi_value;
/** @virtual */
resetFinalizer(): void;
/** @virtual */
data(): void_p;
refcount(): number;
ownership(): ReferenceOwnership;
/** @virtual */
protected callUserFinalizer(): void;
/** @virtual */
protected invokeFinalizerFromGC(): void;
private _setWeak;
finalize(): void;
dispose(): void;
}
export enum ReferenceOwnership {
kRuntime = 0,
kUserland = 1
}
export class ReferenceWithData extends Reference {
private readonly _data;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
private constructor();
data(): void_p;
}
export class ReferenceWithFinalizer extends Reference {
private _finalizer;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
private constructor();
resetFinalizer(): void;
data(): void_p;
protected callUserFinalizer(): void;
protected invokeFinalizerFromGC(): void;
dispose(): void;
}
export class RefTracker {
/** @virtual */
dispose(): void;
/** @virtual */
finalize(): void;
private _next;
private _prev;
link(list: RefTracker): void;
unlink(): void;
static finalizeAll(list: RefTracker): void;
}
export class ScopeStore {
private readonly _rootScope;
currentScope: HandleScope;
private readonly _values;
constructor();
get(id: number): HandleScope | undefined;
openScope(handleStore: HandleStore): HandleScope;
closeScope(): void;
dispose(): void;
}
export class Store<V extends IStoreValue> {
protected _values: Array<V | undefined>;
private _freeList;
private _size;
constructor();
add(value: V): void;
get(id: Ptr): V | undefined;
has(id: Ptr): boolean;
remove(id: Ptr): void;
dispose(): void;
}
export class TrackedFinalizer extends RefTracker {
private _finalizer;
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
private constructor();
data(): void_p;
dispose(): void;
finalize(): void;
}
export class TryCatch {
private _exception;
private _caught;
isEmpty(): boolean;
hasCaught(): boolean;
exception(): any;
setError(err: any): void;
reset(): void;
extractException(): any;
}
export const version: string;
}
+1509
View File
File diff suppressed because it is too large Load Diff
+1510
View File
File diff suppressed because it is too large Load Diff
+671
View File
@@ -0,0 +1,671 @@
export declare type Ptr = number | bigint
export declare interface IBuffer extends Uint8Array {}
export declare interface BufferCtor {
readonly prototype: IBuffer
/** @deprecated */
new (...args: any[]): IBuffer
from: {
(buffer: ArrayBufferLike): IBuffer
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
}
alloc: (size: number) => IBuffer
isBuffer: (obj: unknown) => obj is IBuffer
}
export declare const enum GlobalHandle {
UNDEFINED = 1,
NULL,
FALSE,
TRUE,
GLOBAL
}
export declare const enum Version {
NODE_API_SUPPORTED_VERSION_MIN = 1,
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
NODE_API_SUPPORTED_VERSION_MAX = 10,
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type Pointer<T> = number
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export declare type PointerPointer<T> = number
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
export declare type Const<T> = T
export declare type void_p = Pointer<void>
export declare type void_pp = Pointer<void_p>
export declare type bool = number
export declare type char = number
export declare type char_p = Pointer<char>
export declare type unsigned_char = number
export declare type const_char = Const<char>
export declare type const_char_p = Pointer<const_char>
export declare type char16_t_p = number
export declare type const_char16_t_p = number
export declare type short = number
export declare type unsigned_short = number
export declare type int = number
export declare type unsigned_int = number
export declare type long = number
export declare type unsigned_long = number
export declare type long_long = bigint
export declare type unsigned_long_long = bigint
export declare type float = number
export declare type double = number
export declare type long_double = number
export declare type size_t = number
export declare type int8_t = number
export declare type uint8_t = number
export declare type int16_t = number
export declare type uint16_t = number
export declare type int32_t = number
export declare type uint32_t = number
export declare type int64_t = bigint
export declare type uint64_t = bigint
export declare type napi_env = Pointer<unknown>
export declare type napi_value = Pointer<unknown>
export declare type napi_ref = Pointer<unknown>
export declare type napi_deferred = Pointer<unknown>
export declare type napi_handle_scope = Pointer<unknown>
export declare type napi_escapable_handle_scope = Pointer<unknown>
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
export declare type napi_callback_info = Pointer<unknown>
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
export declare interface napi_extended_error_info {
error_message: const_char_p
engine_reserved: void_p
engine_error_code: uint32_t
error_code: napi_status
}
export declare interface napi_property_descriptor {
// One of utf8name or name should be NULL.
utf8name: const_char_p
name: napi_value
method: napi_callback
getter: napi_callback
setter: napi_callback
value: napi_value
/* napi_property_attributes */
attributes: number
data: void_p
}
export declare type napi_finalize = FunctionPointer<(
env: napi_env,
finalize_data: void_p,
finalize_hint: void_p
) => void>
export declare interface node_module {
nm_version: int32_t
nm_flags: uint32_t
nm_filename: Pointer<const_char>
nm_register_func: napi_addon_register_func
nm_modname: Pointer<const_char>
nm_priv: Pointer<void>
reserved: PointerPointer<void>
}
export declare interface napi_node_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
release: const_char_p
}
export declare interface emnapi_emscripten_version {
major: uint32_t
minor: uint32_t
patch: uint32_t
}
export declare const enum napi_status {
napi_ok,
napi_invalid_arg,
napi_object_expected,
napi_string_expected,
napi_name_expected,
napi_function_expected,
napi_number_expected,
napi_boolean_expected,
napi_array_expected,
napi_generic_failure,
napi_pending_exception,
napi_cancelled,
napi_escape_called_twice,
napi_handle_scope_mismatch,
napi_callback_scope_mismatch,
napi_queue_full,
napi_closing,
napi_bigint_expected,
napi_date_expected,
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
napi_would_deadlock, // unused
napi_no_external_buffers_allowed,
napi_cannot_run_js
}
export declare const enum napi_property_attributes {
napi_default = 0,
napi_writable = 1 << 0,
napi_enumerable = 1 << 1,
napi_configurable = 1 << 2,
// Used with napi_define_class to distinguish static properties
// from instance properties. Ignored by napi_define_properties.
napi_static = 1 << 10,
/// #ifdef NAPI_EXPERIMENTAL
// Default for class methods.
napi_default_method = napi_writable | napi_configurable,
// Default for object properties, like in JS obj[prop].
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
/// #endif // NAPI_EXPERIMENTAL
}
export declare const enum napi_valuetype {
napi_undefined,
napi_null,
napi_boolean,
napi_number,
napi_string,
napi_symbol,
napi_object,
napi_function,
napi_external,
napi_bigint
}
export declare const enum napi_typedarray_type {
napi_int8_array,
napi_uint8_array,
napi_uint8_clamped_array,
napi_int16_array,
napi_uint16_array,
napi_int32_array,
napi_uint32_array,
napi_float32_array,
napi_float64_array,
napi_bigint64_array,
napi_biguint64_array,
napi_float16_array,
}
export declare const enum napi_key_collection_mode {
napi_key_include_prototypes,
napi_key_own_only
}
export declare const enum napi_key_filter {
napi_key_all_properties = 0,
napi_key_writable = 1,
napi_key_enumerable = 1 << 1,
napi_key_configurable = 1 << 2,
napi_key_skip_strings = 1 << 3,
napi_key_skip_symbols = 1 << 4
}
export declare const enum napi_key_conversion {
napi_key_keep_numbers,
napi_key_numbers_to_strings
}
export declare const enum emnapi_memory_view_type {
emnapi_int8_array,
emnapi_uint8_array,
emnapi_uint8_clamped_array,
emnapi_int16_array,
emnapi_uint16_array,
emnapi_int32_array,
emnapi_uint32_array,
emnapi_float32_array,
emnapi_float64_array,
emnapi_bigint64_array,
emnapi_biguint64_array,
emnapi_float16_array,
emnapi_data_view = -1,
emnapi_buffer = -2
}
export declare const enum napi_threadsafe_function_call_mode {
napi_tsfn_nonblocking,
napi_tsfn_blocking
}
export declare const enum napi_threadsafe_function_release_mode {
napi_tsfn_release,
napi_tsfn_abort
}
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
constructor(id: number, value: S);
dispose(): void;
}
export declare class Context {
private _isStopping;
private _canCallIntoJs;
private _suppressDestroy;
envStore: Store<Env>;
scopeStore: ScopeStore;
refStore: Store<Reference>;
deferredStore: Store<Deferred<any>>;
handleStore: HandleStore;
private readonly refCounter?;
private readonly cleanupQueue;
private readonly _externalMemory;
feature: {
supportReflect: boolean;
supportFinalizer: boolean;
supportWeakSymbol: boolean;
supportBigInt: boolean;
supportNewFunction: boolean;
canSetFunctionName: boolean;
setImmediate: (callback: () => void) => void;
Buffer: BufferCtor | undefined;
MessageChannel: {
new (): MessageChannel;
prototype: MessageChannel;
} | undefined;
};
constructor(options?: ContextOptions);
/**
* Suppress the destroy on `beforeExit` event in Node.js.
* Call this method if you want to keep the context and
* all associated {@link Env | Env} alive,
* this also means that cleanup hooks will not be called.
* After call this method, you should call
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
*/
suppressDestroy(): void;
getRuntimeVersions(): {
version: string;
NODE_API_SUPPORTED_VERSION_MAX: Version;
NAPI_VERSION_EXPERIMENTAL: Version;
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
};
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
getCurrentScope(): HandleScope | null;
addToCurrentScope<V>(value: V): Handle<V>;
openScope(envObject?: Env): HandleScope;
closeScope(envObject?: Env, _scope?: HandleScope): void;
ensureHandle<S>(value: S): Handle<S>;
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
runCleanup(): void;
increaseWaitingRequestCounter(): void;
decreaseWaitingRequestCounter(): void;
setCanCallIntoJs(value: boolean): void;
setStopping(value: boolean): void;
canCallIntoJs(): boolean;
/**
* Destroy the context and call cleanup hooks.
* Associated {@link Env | Env} will be destroyed.
*/
destroy(): void;
}
export declare interface ContextOptions {
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
}
export declare function createContext(options?: ContextOptions): Context;
export declare class Deferred<T = any> implements IStoreValue {
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
id: number;
ctx: Context;
value: IDeferrdValue<T>;
constructor(ctx: Context, value: IDeferrdValue<T>);
resolve(value: T): void;
reject(reason?: any): void;
dispose(): void;
}
export declare class EmnapiError extends Error {
constructor(message?: string);
}
export declare abstract class Env implements IStoreValue {
readonly ctx: Context;
moduleApiVersion: number;
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
abort: (msg?: string) => never;
id: number;
openHandleScopes: number;
instanceData: TrackedFinalizer | null;
tryCatch: TryCatch;
refs: number;
reflist: RefTracker;
finalizing_reflist: RefTracker;
pendingFinalizers: RefTracker[];
lastError: {
errorCode: napi_status;
engineErrorCode: number;
engineReserved: Ptr;
};
inGcFinalizer: boolean;
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
/** @virtual */
canCallIntoJs(): boolean;
terminatedOrTerminating(): boolean;
ref(): void;
unref(): void;
ensureHandle<S>(value: S): Handle<S>;
ensureHandleId(value: any): napi_value;
clearLastError(): napi_status;
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
getReturnStatus(): napi_status;
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
/** @virtual */
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
invokeFinalizerFromGC(finalizer: RefTracker): void;
checkGCAccess(): void;
/** @virtual */
enqueueFinalizer(finalizer: RefTracker): void;
/** @virtual */
dequeueFinalizer(finalizer: RefTracker): void;
/** @virtual */
deleteMe(): void;
dispose(): void;
private readonly _bindingMap;
initObjectBinding<S extends object>(value: S): IReferenceBinding;
getObjectBinding<S extends object>(value: S): IReferenceBinding;
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
getInstanceData(): number;
}
/** @public */
declare interface External_2 extends Record<any, any> {
}
/** @public */
declare const External_2: {
new (value: number | bigint): External_2;
prototype: null;
};
export { External_2 as External }
export declare class Finalizer {
envObject: Env;
private _finalizeCallback;
private _finalizeData;
private _finalizeHint;
private _makeDynCall_vppp;
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
callback(): napi_finalize;
data(): void_p;
hint(): void_p;
resetEnv(): void;
resetFinalizer(): void;
callFinalizer(): void;
dispose(): void;
}
export declare function getDefaultContext(): Context;
/** @public */
export declare function getExternalValue(external: External_2): number | bigint;
export declare class Handle<S> {
id: number;
value: S;
constructor(id: number, value: S);
data(): void_p;
isNumber(): boolean;
isBigInt(): boolean;
isString(): boolean;
isFunction(): boolean;
isExternal(): boolean;
isObject(): boolean;
isArray(): boolean;
isArrayBuffer(): boolean;
isTypedArray(): boolean;
isBuffer(BufferConstructor?: BufferCtor): boolean;
isDataView(): boolean;
isDate(): boolean;
isPromise(): boolean;
isBoolean(): boolean;
isUndefined(): boolean;
isSymbol(): boolean;
isNull(): boolean;
dispose(): void;
}
export declare class HandleScope {
handleStore: HandleStore;
id: number;
parent: HandleScope | null;
child: HandleScope | null;
start: number;
end: number;
private _escapeCalled;
callbackInfo: ICallbackInfo;
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
add<V>(value: V): Handle<V>;
addExternal(data: void_p): Handle<object>;
dispose(): void;
escape(handle: number): Handle<any> | null;
escapeCalled(): boolean;
}
export declare class HandleStore {
static UNDEFINED: ConstHandle<undefined>;
static NULL: ConstHandle<null>;
static FALSE: ConstHandle<false>;
static TRUE: ConstHandle<true>;
static GLOBAL: ConstHandle<typeof globalThis>;
static MIN_ID: 6;
private readonly _values;
private _next;
push<S>(value: S): Handle<S>;
erase(start: number, end: number): void;
get(id: Ptr): Handle<any> | undefined;
swap(a: number, b: number): void;
dispose(): void;
}
export declare interface ICallbackInfo {
thiz: any;
data: void_p;
args: ArrayLike<any>;
fn: Function;
}
export declare interface IDeferrdValue<T = any> {
resolve: (value: T) => void;
reject: (reason?: any) => void;
}
export declare interface IReferenceBinding {
wrapped: number;
tag: Uint32Array | null;
}
/** @public */
export declare function isExternal(object: unknown): object is External_2;
export declare function isReferenceType(v: any): v is object;
export declare interface IStoreValue {
id: number;
dispose(): void;
[x: string]: any;
}
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
export declare class NodeEnv extends Env {
filename: string;
private readonly nodeBinding?;
destructing: boolean;
finalizationScheduled: boolean;
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
deleteMe(): void;
canCallIntoJs(): boolean;
triggerFatalException(err: any): void;
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
enqueueFinalizer(finalizer: RefTracker): void;
drainFinalizerQueue(): void;
}
export declare class NotSupportBufferError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class NotSupportWeakRefError extends EmnapiError {
constructor(api: string, message: string);
}
export declare class Persistent<T> {
private _ref;
private _param;
private _callback;
private static readonly _registry;
constructor(value: T);
setWeak<P>(param: P, callback: (param: P) => void): void;
clearWeak(): void;
reset(): void;
isEmpty(): boolean;
deref(): T | undefined;
}
export declare class Reference extends RefTracker implements IStoreValue {
private static weakCallback;
id: number;
envObject: Env;
private readonly canBeWeak;
private _refcount;
private readonly _ownership;
persistent: Persistent<object>;
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
ref(): number;
unref(): number;
get(envObject?: Env): napi_value;
/** @virtual */
resetFinalizer(): void;
/** @virtual */
data(): void_p;
refcount(): number;
ownership(): ReferenceOwnership;
/** @virtual */
protected callUserFinalizer(): void;
/** @virtual */
protected invokeFinalizerFromGC(): void;
private _setWeak;
finalize(): void;
dispose(): void;
}
export declare enum ReferenceOwnership {
kRuntime = 0,
kUserland = 1
}
export declare class ReferenceWithData extends Reference {
private readonly _data;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
private constructor();
data(): void_p;
}
export declare class ReferenceWithFinalizer extends Reference {
private _finalizer;
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
private constructor();
resetFinalizer(): void;
data(): void_p;
protected callUserFinalizer(): void;
protected invokeFinalizerFromGC(): void;
dispose(): void;
}
export declare class RefTracker {
/** @virtual */
dispose(): void;
/** @virtual */
finalize(): void;
private _next;
private _prev;
link(list: RefTracker): void;
unlink(): void;
static finalizeAll(list: RefTracker): void;
}
export declare class ScopeStore {
private readonly _rootScope;
currentScope: HandleScope;
private readonly _values;
constructor();
get(id: number): HandleScope | undefined;
openScope(handleStore: HandleStore): HandleScope;
closeScope(): void;
dispose(): void;
}
export declare class Store<V extends IStoreValue> {
protected _values: Array<V | undefined>;
private _freeList;
private _size;
constructor();
add(value: V): void;
get(id: Ptr): V | undefined;
has(id: Ptr): boolean;
remove(id: Ptr): void;
dispose(): void;
}
export declare class TrackedFinalizer extends RefTracker {
private _finalizer;
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
private constructor();
data(): void_p;
dispose(): void;
finalize(): void;
}
export declare class TryCatch {
private _exception;
private _caught;
isEmpty(): boolean;
hasCaught(): boolean;
exception(): any;
setError(err: any): void;
reset(): void;
extractException(): any;
}
export declare const version: string;
export { }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1350
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production') {
module.exports = require('./dist/emnapi.cjs.min.js')
} else {
module.exports = require('./dist/emnapi.cjs.js')
}
+48
View File
@@ -0,0 +1,48 @@
{
"name": "@emnapi/runtime",
"version": "1.10.0",
"description": "emnapi runtime",
"main": "index.js",
"module": "./dist/emnapi.esm-bundler.js",
"types": "./dist/emnapi.d.ts",
"sideEffects": false,
"exports": {
".": {
"types": {
"module": "./dist/emnapi.d.ts",
"import": "./dist/emnapi.d.mts",
"default": "./dist/emnapi.d.ts"
},
"module": "./dist/emnapi.esm-bundler.js",
"import": "./dist/emnapi.mjs",
"default": "./index.js"
},
"./dist/emnapi.cjs.min": {
"types": "./dist/emnapi.d.ts",
"default": "./dist/emnapi.cjs.min.js"
},
"./dist/emnapi.min.mjs": {
"types": "./dist/emnapi.d.mts",
"default": "./dist/emnapi.min.mjs"
}
},
"dependencies": {
"tslib": "^2.4.0"
},
"scripts": {
"build": "node ./script/build.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/toyobayashi/emnapi.git"
},
"author": "toyobayashi",
"license": "MIT",
"bugs": {
"url": "https://github.com/toyobayashi/emnapi/issues"
},
"homepage": "https://github.com/toyobayashi/emnapi#readme",
"publishConfig": {
"access": "public"
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-present Toyobayashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+203
View File
@@ -0,0 +1,203 @@
# @emnapi/wasi-threads
This package makes [wasi-threads proposal](https://github.com/WebAssembly/wasi-threads) based WASI modules work in Node.js and browser.
## Quick Start
`index.html`
```html
<script src="./node_modules/@tybys/wasm-util/dist/wasm-util.js"></script>
<script src="./node_modules/@emnapi/wasi-threads/dist/wasi-threads.js"></script>
<script src="./index.js"></script>
```
If your application will block browser main thread (for example `pthread_join`), please run it in worker instead.
```html
<script>
// pthread_join (Atomics.wait) cannot be called in browser main thread
new Worker('./index.js')
</script>
```
`index.js`
```js
const ENVIRONMENT_IS_NODE =
typeof process === 'object' && process !== null &&
typeof process.versions === 'object' && process.versions !== null &&
typeof process.versions.node === 'string';
(function (main) {
if (ENVIRONMENT_IS_NODE) {
main(require)
} else {
if (typeof importScripts === 'function') {
importScripts('./node_modules/@tybys/wasm-util/dist/wasm-util.js')
importScripts('./node_modules/@emnapi/wasi-threads/dist/wasi-threads.js')
}
const nodeWasi = { WASI: globalThis.wasmUtil.WASI }
const nodeWorkerThreads = {
Worker: globalThis.Worker
}
const _require = function (request) {
if (request === 'node:wasi' || request === 'wasi') return nodeWasi
if (request === 'node:worker_threads' || request === 'worker_threads') return nodeWorkerThreads
if (request === '@emnapi/wasi-threads') return globalThis.wasiThreads
throw new Error('Can not find module: ' + request)
}
main(_require)
}
})(async function (require) {
const { WASI } = require('wasi')
const { Worker } = require('worker_threads')
const { WASIThreads } = require('@emnapi/wasi-threads')
const wasi = new WASI({
version: 'preview1'
})
const wasiThreads = new WASIThreads({
wasi,
/**
* avoid Atomics.wait() deadlock during thread creation in browser
* see https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size
*/
reuseWorker: ENVIRONMENT_IS_NODE
? false
: {
size: 4 /** greater than actual needs (2) */,
strict: true
},
/**
* Synchronous thread creation
* pthread_create will not return until thread worker actually starts
*/
waitThreadStart: typeof window === 'undefined' ? 1000 : false,
onCreateWorker: () => {
return new Worker('./worker.js', {
execArgv: ['--experimental-wasi-unstable-preview1']
})
}
})
const memory = new WebAssembly.Memory({
initial: 16777216 / 65536,
maximum: 2147483648 / 65536,
shared: true
})
let input
const file = 'path/to/your/wasi-module.wasm'
try {
input = require('fs').readFileSync(require('path').join(__dirname, file))
} catch (err) {
const response = await fetch(file)
input = await response.arrayBuffer()
}
let { module, instance } = await WebAssembly.instantiate(input, {
env: { memory },
wasi_snapshot_preview1: wasi.wasiImport,
...wasiThreads.getImportObject()
})
wasiThreads.setup(instance, module, memory)
await wasiThreads.preloadWorkers()
if (typeof instance.exports._start === 'function') {
return wasi.start(instance)
} else {
wasi.initialize(instance)
// instance.exports.exported_wasm_function()
}
})
```
`worker.js`
```js
(function (main) {
const ENVIRONMENT_IS_NODE =
typeof process === 'object' && process !== null &&
typeof process.versions === 'object' && process.versions !== null &&
typeof process.versions.node === 'string'
if (ENVIRONMENT_IS_NODE) {
const _require = function (request) {
return require(request)
}
const _init = function () {
const nodeWorkerThreads = require('worker_threads')
const parentPort = nodeWorkerThreads.parentPort
parentPort.on('message', (data) => {
globalThis.onmessage({ data })
})
Object.assign(globalThis, {
self: globalThis,
require,
Worker: nodeWorkerThreads.Worker,
importScripts: function (f) {
(0, eval)(require('fs').readFileSync(f, 'utf8') + '//# sourceURL=' + f)
},
postMessage: function (msg) {
parentPort.postMessage(msg)
}
})
}
main(_require, _init)
} else {
importScripts('./node_modules/@tybys/wasm-util/dist/wasm-util.js')
importScripts('./node_modules/@emnapi/wasi-threads/dist/wasi-threads.js')
const nodeWasi = { WASI: globalThis.wasmUtil.WASI }
const _require = function (request) {
if (request === '@emnapi/wasi-threads') return globalThis.wasiThreads
if (request === 'node:wasi' || request === 'wasi') return nodeWasi
throw new Error('Can not find module: ' + request)
}
const _init = function () {}
main(_require, _init)
}
})(function main (require, init) {
init()
const { WASI } = require('wasi')
const { ThreadMessageHandler, WASIThreads } = require('@emnapi/wasi-threads')
const handler = new ThreadMessageHandler({
async onLoad ({ wasmModule, wasmMemory }) {
const wasi = new WASI({
version: 'preview1'
})
const wasiThreads = new WASIThreads({
wasi,
childThread: true
})
const originalInstance = await WebAssembly.instantiate(wasmModule, {
env: {
memory: wasmMemory,
},
wasi_snapshot_preview1: wasi.wasiImport,
...wasiThreads.getImportObject()
})
// must call `initialize` instead of `start` in child thread
const instance = wasiThreads.initialize(originalInstance, wasmModule, wasmMemory)
return { module: wasmModule, instance }
}
})
globalThis.onmessage = function (e) {
handler.handle(e)
// handle other messages
}
})
```
+894
View File
@@ -0,0 +1,894 @@
const _WebAssembly = typeof WebAssembly !== 'undefined'
? WebAssembly
: typeof WXWebAssembly !== 'undefined'
? WXWebAssembly
: undefined;
const ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
typeof process.versions === 'object' && process.versions !== null &&
typeof process.versions.node === 'string';
function getPostMessage(options) {
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
? options.postMessage
: typeof postMessage === 'function'
? postMessage
: undefined;
}
function serizeErrorToBuffer(sab, code, error) {
const i32array = new Int32Array(sab);
Atomics.store(i32array, 0, code);
if (code > 1 && error) {
const name = error.name;
const message = error.message;
const stack = error.stack;
const nameBuffer = new TextEncoder().encode(name);
const messageBuffer = new TextEncoder().encode(message);
const stackBuffer = new TextEncoder().encode(stack);
Atomics.store(i32array, 1, nameBuffer.length);
Atomics.store(i32array, 2, messageBuffer.length);
Atomics.store(i32array, 3, stackBuffer.length);
const buffer = new Uint8Array(sab);
buffer.set(nameBuffer, 16);
buffer.set(messageBuffer, 16 + nameBuffer.length);
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
}
}
function deserizeErrorFromBuffer(sab) {
var _a, _b;
const i32array = new Int32Array(sab);
const status = Atomics.load(i32array, 0);
if (status <= 1) {
return null;
}
const nameLength = Atomics.load(i32array, 1);
const messageLength = Atomics.load(i32array, 2);
const stackLength = Atomics.load(i32array, 3);
const buffer = new Uint8Array(sab);
const nameBuffer = buffer.slice(16, 16 + nameLength);
const messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
const stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
const name = new TextDecoder().decode(nameBuffer);
const message = new TextDecoder().decode(messageBuffer);
const stack = new TextDecoder().decode(stackBuffer);
const ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
const error = new ErrorConstructor(message);
Object.defineProperty(error, 'stack', {
value: stack,
writable: true,
enumerable: false,
configurable: true
});
return error;
}
function isSharedArrayBuffer(value) {
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
}
function isTrapError(e) {
try {
return e instanceof _WebAssembly.RuntimeError;
}
catch (_) {
return false;
}
}
function createMessage(type, payload) {
return {
__emnapi__: {
type,
payload
}
};
}
const WASI_THREADS_MAX_TID = 0x1FFFFFFF;
function checkSharedWasmMemory(wasmMemory) {
if (wasmMemory) {
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
throw new Error('Multithread features require shared wasm memory. ' +
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
'then create WebAssembly.Memory with `shared: true` option');
}
}
else {
if (typeof SharedArrayBuffer === 'undefined') {
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
}
}
}
function getReuseWorker(value) {
var _a;
if (typeof value === 'boolean') {
return value ? { size: 0, strict: false } : false;
}
if (typeof value === 'number') {
if (!(value >= 0)) {
throw new RangeError('reuseWorker: size must be a non-negative integer');
}
return { size: value, strict: false };
}
if (!value) {
return false;
}
const size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
const strict = Boolean(value.strict);
if (!(size > 0) && strict) {
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
}
return { size, strict };
}
let nextWorkerID = 0;
class ThreadManager {
get nextWorkerID() { return nextWorkerID; }
constructor(options) {
var _a;
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.wasmModule = null;
this.wasmMemory = null;
this.messageEvents = new WeakMap();
if (!options) {
throw new TypeError('ThreadManager(): options is not provided');
}
if ('childThread' in options) {
this._childThread = Boolean(options.childThread);
}
else {
this._childThread = false;
}
if (this._childThread) {
this._onCreateWorker = undefined;
this._reuseWorker = false;
this._beforeLoad = undefined;
}
else {
this._onCreateWorker = options.onCreateWorker;
this._reuseWorker = getReuseWorker(options.reuseWorker);
this._beforeLoad = options.beforeLoad;
}
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
this.threadSpawn = options.threadSpawn;
}
init() {
if (!this._childThread) {
this.initMainThread();
}
}
initMainThread() {
this.preparePool();
}
preparePool() {
if (this._reuseWorker) {
if (this._reuseWorker.size) {
let pthreadPoolSize = this._reuseWorker.size;
while (pthreadPoolSize--) {
const worker = this.allocateUnusedWorker();
if (ENVIRONMENT_IS_NODE) {
worker.once('message', () => { });
worker.unref();
}
}
}
}
}
shouldPreloadWorkers() {
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
}
loadWasmModuleToAllWorkers() {
const promises = Array(this.unusedWorkers.length);
for (let i = 0; i < this.unusedWorkers.length; ++i) {
const worker = this.unusedWorkers[i];
if (ENVIRONMENT_IS_NODE)
worker.ref();
promises[i] = this.loadWasmModuleToWorker(worker).then((w) => {
if (ENVIRONMENT_IS_NODE)
worker.unref();
return w;
}, (e) => {
if (ENVIRONMENT_IS_NODE)
worker.unref();
throw e;
});
}
return Promise.all(promises).catch((err) => {
this.terminateAllThreads();
throw err;
});
}
preloadWorkers() {
if (this.shouldPreloadWorkers()) {
return this.loadWasmModuleToAllWorkers();
}
return Promise.resolve([]);
}
setup(wasmModule, wasmMemory) {
this.wasmModule = wasmModule;
this.wasmMemory = wasmMemory;
}
markId(worker) {
if (worker.__emnapi_tid)
return worker.__emnapi_tid;
const tid = nextWorkerID + 43;
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
this.pthreads[tid] = worker;
worker.__emnapi_tid = tid;
return tid;
}
returnWorkerToPool(worker) {
var tid = worker.__emnapi_tid;
if (tid !== undefined) {
delete this.pthreads[tid];
}
this.unusedWorkers.push(worker);
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
delete worker.__emnapi_tid;
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
}
loadWasmModuleToWorker(worker, sab) {
if (worker.whenLoaded)
return worker.whenLoaded;
const err = this.printErr;
const beforeLoad = this._beforeLoad;
const _this = this;
worker.whenLoaded = new Promise((resolve, reject) => {
const handleError = function (e) {
let message = 'worker sent an error!';
if (worker.__emnapi_tid !== undefined) {
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
}
if ('message' in e) {
err(message + ' ' + e.message);
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
try {
_this.terminateAllThreads();
}
catch (_) { }
}
}
else {
err(message);
}
reject(e);
throw e;
};
const handleMessage = (data) => {
if (data.__emnapi__) {
const type = data.__emnapi__.type;
const payload = data.__emnapi__.payload;
if (type === 'loaded') {
worker.loaded = true;
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
worker.unref();
}
resolve(worker);
}
else if (type === 'cleanup-thread') {
if (payload.tid in this.pthreads) {
this.cleanThread(worker, payload.tid);
}
}
else if (type === 'spawn-thread') {
this.threadSpawn(payload.startArg, payload.errorOrTid);
}
else if (type === 'terminate-all-threads') {
this.terminateAllThreads();
}
}
};
worker.onmessage = (e) => {
handleMessage(e.data);
this.fireMessageEvent(worker, e);
};
worker.onerror = handleError;
if (ENVIRONMENT_IS_NODE) {
worker.on('message', function (data) {
var _a, _b;
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
data
});
});
worker.on('error', function (e) {
var _a, _b;
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
});
worker.on('detachedExit', function () { });
}
if (typeof beforeLoad === 'function') {
beforeLoad(worker);
}
try {
worker.postMessage(createMessage('load', {
wasmModule: this.wasmModule,
wasmMemory: this.wasmMemory,
sab
}));
}
catch (err) {
checkSharedWasmMemory(this.wasmMemory);
throw err;
}
});
return worker.whenLoaded;
}
allocateUnusedWorker() {
const _onCreateWorker = this._onCreateWorker;
if (typeof _onCreateWorker !== 'function') {
throw new TypeError('`options.onCreateWorker` is not provided');
}
const worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
this.unusedWorkers.push(worker);
return worker;
}
getNewWorker(sab) {
if (this._reuseWorker) {
if (this.unusedWorkers.length === 0) {
if (this._reuseWorker.strict) {
if (!ENVIRONMENT_IS_NODE) {
const err = this.printErr;
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
return;
}
}
const worker = this.allocateUnusedWorker();
this.loadWasmModuleToWorker(worker, sab);
}
return this.unusedWorkers.pop();
}
const worker = this.allocateUnusedWorker();
this.loadWasmModuleToWorker(worker, sab);
return this.unusedWorkers.pop();
}
cleanThread(worker, tid, force) {
if (!force && this._reuseWorker) {
this.returnWorkerToPool(worker);
}
else {
delete this.pthreads[tid];
const index = this.runningWorkers.indexOf(worker);
if (index !== -1) {
this.runningWorkers.splice(index, 1);
}
this.terminateWorker(worker);
delete worker.__emnapi_tid;
}
}
terminateWorker(worker) {
var _a;
const tid = worker.__emnapi_tid;
worker.terminate();
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
this.messageEvents.delete(worker);
worker.onmessage = (e) => {
if (e.data.__emnapi__) {
const err = this.printErr;
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
}
};
}
terminateAllThreads() {
for (let i = 0; i < this.runningWorkers.length; ++i) {
this.terminateWorker(this.runningWorkers[i]);
}
for (let i = 0; i < this.unusedWorkers.length; ++i) {
this.terminateWorker(this.unusedWorkers[i]);
}
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.preparePool();
}
addMessageEventListener(worker, onMessage) {
let listeners = this.messageEvents.get(worker);
if (!listeners) {
listeners = new Set();
this.messageEvents.set(worker, listeners);
}
listeners.add(onMessage);
return () => {
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
};
}
fireMessageEvent(worker, e) {
const listeners = this.messageEvents.get(worker);
if (!listeners)
return;
const err = this.printErr;
listeners.forEach((listener) => {
try {
listener(e);
}
catch (e) {
err(e.stack);
}
});
}
}
const kIsProxy = Symbol('kIsProxy');
function createInstanceProxy(instance, memory) {
if (instance[kIsProxy])
return instance;
const originalExports = instance.exports;
const createHandler = function (target) {
const handlers = [
'apply',
'construct',
'defineProperty',
'deleteProperty',
'get',
'getOwnPropertyDescriptor',
'getPrototypeOf',
'has',
'isExtensible',
'ownKeys',
'preventExtensions',
'set',
'setPrototypeOf'
];
const handler = {};
for (let i = 0; i < handlers.length; i++) {
const name = handlers[i];
handler[name] = function () {
const args = Array.prototype.slice.call(arguments, 1);
args.unshift(target);
return Reflect[name].apply(Reflect, args);
};
}
return handler;
};
const handler = createHandler(originalExports);
const _initialize = () => { };
const _start = () => 0;
handler.get = function (_target, p, receiver) {
var _a;
if (p === 'memory') {
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
}
if (p === '_initialize') {
return p in originalExports ? _initialize : undefined;
}
if (p === '_start') {
return p in originalExports ? _start : undefined;
}
return Reflect.get(originalExports, p, receiver);
};
handler.has = function (_target, p) {
if (p === 'memory')
return true;
return Reflect.has(originalExports, p);
};
const exportsProxy = new Proxy(Object.create(null), handler);
return new Proxy(instance, {
get(target, p, receiver) {
if (p === 'exports') {
return exportsProxy;
}
if (p === kIsProxy) {
return true;
}
return Reflect.get(target, p, receiver);
}
});
}
const patchedWasiInstances = new WeakMap();
class WASIThreads {
constructor(options) {
if (!options) {
throw new TypeError('WASIThreads(): options is not provided');
}
if (!options.wasi) {
throw new TypeError('WASIThreads(): options.wasi is not provided');
}
patchedWasiInstances.set(this, new WeakSet());
const wasi = options.wasi;
patchWasiInstance(this, wasi);
this.wasi = wasi;
if ('childThread' in options) {
this.childThread = Boolean(options.childThread);
}
else {
this.childThread = false;
}
this.PThread = undefined;
if ('threadManager' in options) {
if (typeof options.threadManager === 'function') {
this.PThread = options.threadManager();
}
else {
this.PThread = options.threadManager;
}
}
else {
if (!this.childThread) {
this.PThread = new ThreadManager(options);
this.PThread.init();
}
}
let waitThreadStart = false;
if ('waitThreadStart' in options) {
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
}
const postMessage = getPostMessage(options);
if (this.childThread && typeof postMessage !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMessage;
const wasm64 = Boolean(options.wasm64);
const threadSpawn = (startArg, errorOrTid) => {
var _a;
const EAGAIN = 6;
const isNewABI = errorOrTid !== undefined;
try {
checkSharedWasmMemory(this.wasmMemory);
}
catch (err) {
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
if (isNewABI) {
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct, 0, 1);
Atomics.store(struct, 1, EAGAIN);
Atomics.notify(struct, 1);
return 1;
}
else {
return -EAGAIN;
}
}
if (!isNewABI) {
const malloc = this.wasmInstance.exports.malloc;
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
if (!errorOrTid) {
return -48;
}
}
const _free = this.wasmInstance.exports.free;
const free = wasm64 ? (ptr) => { _free(BigInt(ptr)); } : _free;
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, 0);
if (this.childThread) {
postMessage(createMessage('spawn-thread', {
startArg,
errorOrTid: errorOrTid
}));
Atomics.wait(struct, 1, 0);
const isError = Atomics.load(struct, 0);
const result = Atomics.load(struct, 1);
if (isNewABI) {
return isError;
}
free(errorOrTid);
return isError ? -result : result;
}
const shouldWait = waitThreadStart || (waitThreadStart === 0);
let sab;
if (shouldWait) {
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
Atomics.store(sab, 0, 0);
}
let worker;
let tid;
const PThread = this.PThread;
try {
worker = PThread.getNewWorker(sab);
if (!worker) {
throw new Error('failed to get new worker');
}
tid = PThread.markId(worker);
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
worker.postMessage(createMessage('start', {
tid,
arg: startArg,
sab
}));
if (shouldWait) {
if (typeof waitThreadStart === 'number') {
const waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
if (waitResult === 'timed-out') {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
}
}
else {
Atomics.wait(sab, 0, 0);
}
const r = Atomics.load(sab, 0);
if (r > 1) {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw deserizeErrorFromBuffer(sab.buffer);
}
}
}
catch (e) {
Atomics.store(struct, 0, 1);
Atomics.store(struct, 1, EAGAIN);
Atomics.notify(struct, 1);
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
if (isNewABI) {
return 1;
}
free(errorOrTid);
return -EAGAIN;
}
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, tid);
Atomics.notify(struct, 1);
PThread.runningWorkers.push(worker);
if (!shouldWait) {
worker.whenLoaded.catch((err) => {
delete worker.whenLoaded;
PThread.cleanThread(worker, tid, true);
throw err;
});
}
if (isNewABI) {
return 0;
}
free(errorOrTid);
return tid;
};
this.threadSpawn = threadSpawn;
if (this.PThread) {
this.PThread.threadSpawn = threadSpawn;
}
}
getImportObject() {
return {
wasi: {
'thread-spawn': this.threadSpawn
}
};
}
setup(wasmInstance, wasmModule, wasmMemory) {
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
this.wasmInstance = wasmInstance;
this.wasmMemory = wasmMemory;
if (this.PThread) {
this.PThread.setup(wasmModule, wasmMemory);
}
}
preloadWorkers() {
if (this.PThread) {
return this.PThread.preloadWorkers();
}
return Promise.resolve([]);
}
initialize(instance, module, memory) {
const exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
const wasi = this.wasi;
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
if (this.childThread) {
wasi.start(instance);
try {
const kStarted = getWasiSymbol(wasi, 'kStarted');
wasi[kStarted] = false;
}
catch (_) { }
}
else {
setupInstance(wasi, instance);
}
}
else {
wasi.initialize(instance);
}
return instance;
}
start(instance, module, memory) {
const exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
const exitCode = this.wasi.start(instance);
return { exitCode, instance };
}
terminateAllThreads() {
var _a;
if (!this.childThread) {
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
}
else {
this.postMessage(createMessage('terminate-all-threads', {}));
}
}
}
function patchWasiInstance(wasiThreads, wasi) {
const patched = patchedWasiInstances.get(wasiThreads);
if (patched.has(wasi)) {
return;
}
const _this = wasiThreads;
const wasiImport = wasi.wasiImport;
if (wasiImport) {
const proc_exit = wasiImport.proc_exit;
wasiImport.proc_exit = function (code) {
_this.terminateAllThreads();
return proc_exit.call(this, code);
};
}
if (!_this.childThread) {
const start = wasi.start;
if (typeof start === 'function') {
wasi.start = function (instance) {
try {
return start.call(this, instance);
}
catch (err) {
if (isTrapError(err)) {
_this.terminateAllThreads();
}
throw err;
}
};
}
}
patched.add(wasi);
}
function getWasiSymbol(wasi, description) {
const symbols = Object.getOwnPropertySymbols(wasi);
const selectDescription = (description) => (s) => {
if (s.description) {
return s.description === description;
}
return s.toString() === `Symbol(${description})`;
};
if (Array.isArray(description)) {
return description.map(d => symbols.filter(selectDescription(d))[0]);
}
return symbols.filter(selectDescription(description))[0];
}
function setupInstance(wasi, instance) {
const [kInstance, kSetMemory] = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']);
wasi[kInstance] = instance;
wasi[kSetMemory](instance.exports.memory);
}
class ThreadMessageHandler {
constructor(options) {
const postMsg = getPostMessage(options);
if (typeof postMsg !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMsg;
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : (_type, err) => { throw err; };
this.instance = undefined;
this.messagesBeforeLoad = [];
}
instantiate(data) {
if (typeof this.onLoad === 'function') {
return this.onLoad(data);
}
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
}
handle(e) {
var _a;
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
const type = e.data.__emnapi__.type;
const payload = e.data.__emnapi__.payload;
try {
if (type === 'load') {
this._load(payload);
}
else if (type === 'start') {
this.handleAfterLoad(e, () => {
this._start(payload);
});
}
}
catch (err) {
this.onError(err, type);
}
}
}
_load(payload) {
if (this.instance !== undefined)
return;
let source;
try {
source = this.instantiate(payload);
}
catch (err) {
this._loaded(err, null, payload);
return;
}
const then = source && 'then' in source ? source.then : undefined;
if (typeof then === 'function') {
then.call(source, (source) => { this._loaded(null, source, payload); }, (err) => { this._loaded(err, null, payload); });
}
else {
this._loaded(null, source, payload);
}
}
_start(payload) {
const wasi_thread_start = this.instance.exports.wasi_thread_start;
if (typeof wasi_thread_start !== 'function') {
const err = new TypeError('wasi_thread_start is not exported');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
const postMessage = this.postMessage;
const tid = payload.tid;
const startArg = payload.arg;
notifyPthreadCreateResult(payload.sab, 1);
try {
wasi_thread_start(tid, startArg);
}
catch (err) {
if (err !== 'unwind') {
throw err;
}
else {
return;
}
}
postMessage(createMessage('cleanup-thread', { tid }));
}
_loaded(err, source, payload) {
if (err) {
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
if (source == null) {
const err = new TypeError('onLoad should return an object');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
const instance = source.instance;
if (!instance) {
const err = new TypeError('onLoad should return an object which includes "instance"');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
this.instance = instance;
const postMessage = this.postMessage;
postMessage(createMessage('loaded', {}));
const messages = this.messagesBeforeLoad;
this.messagesBeforeLoad = [];
for (let i = 0; i < messages.length; i++) {
const data = messages[i];
this.handle({ data });
}
}
handleAfterLoad(e, f) {
if (this.instance !== undefined) {
f.call(this, e);
}
else {
this.messagesBeforeLoad.push(e.data);
}
}
}
function notifyPthreadCreateResult(sab, result, error) {
if (sab) {
serizeErrorToBuffer(sab.buffer, result, error);
Atomics.notify(sab, 0);
}
}
exports.ThreadManager = ThreadManager;
exports.ThreadMessageHandler = ThreadMessageHandler;
exports.WASIThreads = WASIThreads;
exports.createInstanceProxy = createInstanceProxy;
exports.isSharedArrayBuffer = isSharedArrayBuffer;
exports.isTrapError = isTrapError;
+272
View File
@@ -0,0 +1,272 @@
/// <reference types="node" />
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
File diff suppressed because one or more lines are too long
+272
View File
@@ -0,0 +1,272 @@
/// <reference types="node" />
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
+274
View File
@@ -0,0 +1,274 @@
/// <reference types="node" />
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
export as namespace wasiThreads;
+942
View File
@@ -0,0 +1,942 @@
var _WebAssembly = typeof WebAssembly !== 'undefined'
? WebAssembly
: typeof WXWebAssembly !== 'undefined'
? WXWebAssembly
: undefined;
var ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
typeof process.versions === 'object' && process.versions !== null &&
typeof process.versions.node === 'string';
function getPostMessage(options) {
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
? options.postMessage
: typeof postMessage === 'function'
? postMessage
: undefined;
}
function serizeErrorToBuffer(sab, code, error) {
var i32array = new Int32Array(sab);
Atomics.store(i32array, 0, code);
if (code > 1 && error) {
var name_1 = error.name;
var message = error.message;
var stack = error.stack;
var nameBuffer = new TextEncoder().encode(name_1);
var messageBuffer = new TextEncoder().encode(message);
var stackBuffer = new TextEncoder().encode(stack);
Atomics.store(i32array, 1, nameBuffer.length);
Atomics.store(i32array, 2, messageBuffer.length);
Atomics.store(i32array, 3, stackBuffer.length);
var buffer = new Uint8Array(sab);
buffer.set(nameBuffer, 16);
buffer.set(messageBuffer, 16 + nameBuffer.length);
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
}
}
function deserizeErrorFromBuffer(sab) {
var _a, _b;
var i32array = new Int32Array(sab);
var status = Atomics.load(i32array, 0);
if (status <= 1) {
return null;
}
var nameLength = Atomics.load(i32array, 1);
var messageLength = Atomics.load(i32array, 2);
var stackLength = Atomics.load(i32array, 3);
var buffer = new Uint8Array(sab);
var nameBuffer = buffer.slice(16, 16 + nameLength);
var messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
var stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
var name = new TextDecoder().decode(nameBuffer);
var message = new TextDecoder().decode(messageBuffer);
var stack = new TextDecoder().decode(stackBuffer);
var ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
var error = new ErrorConstructor(message);
Object.defineProperty(error, 'stack', {
value: stack,
writable: true,
enumerable: false,
configurable: true
});
return error;
}
/** @public */
function isSharedArrayBuffer(value) {
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
}
/** @public */
function isTrapError(e) {
try {
return e instanceof _WebAssembly.RuntimeError;
}
catch (_) {
return false;
}
}
function createMessage(type, payload) {
return {
__emnapi__: {
type: type,
payload: payload
}
};
}
var WASI_THREADS_MAX_TID = 0x1FFFFFFF;
function checkSharedWasmMemory(wasmMemory) {
if (wasmMemory) {
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
throw new Error('Multithread features require shared wasm memory. ' +
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
'then create WebAssembly.Memory with `shared: true` option');
}
}
else {
if (typeof SharedArrayBuffer === 'undefined') {
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
}
}
}
function getReuseWorker(value) {
var _a;
if (typeof value === 'boolean') {
return value ? { size: 0, strict: false } : false;
}
if (typeof value === 'number') {
if (!(value >= 0)) {
throw new RangeError('reuseWorker: size must be a non-negative integer');
}
return { size: value, strict: false };
}
if (!value) {
return false;
}
var size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
var strict = Boolean(value.strict);
if (!(size > 0) && strict) {
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
}
return { size: size, strict: strict };
}
var nextWorkerID = 0;
/** @public */
var ThreadManager = /*#__PURE__*/ (function () {
function ThreadManager(options) {
var _a;
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.wasmModule = null;
this.wasmMemory = null;
this.messageEvents = new WeakMap();
if (!options) {
throw new TypeError('ThreadManager(): options is not provided');
}
if ('childThread' in options) {
this._childThread = Boolean(options.childThread);
}
else {
this._childThread = false;
}
if (this._childThread) {
this._onCreateWorker = undefined;
this._reuseWorker = false;
this._beforeLoad = undefined;
}
else {
this._onCreateWorker = options.onCreateWorker;
this._reuseWorker = getReuseWorker(options.reuseWorker);
this._beforeLoad = options.beforeLoad;
}
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
this.threadSpawn = options.threadSpawn;
}
Object.defineProperty(ThreadManager.prototype, "nextWorkerID", {
get: function () { return nextWorkerID; },
enumerable: false,
configurable: true
});
ThreadManager.prototype.init = function () {
if (!this._childThread) {
this.initMainThread();
}
};
ThreadManager.prototype.initMainThread = function () {
this.preparePool();
};
ThreadManager.prototype.preparePool = function () {
if (this._reuseWorker) {
if (this._reuseWorker.size) {
var pthreadPoolSize = this._reuseWorker.size;
while (pthreadPoolSize--) {
var worker = this.allocateUnusedWorker();
if (ENVIRONMENT_IS_NODE) {
// https://github.com/nodejs/node/issues/53036
worker.once('message', function () { });
worker.unref();
}
}
}
}
};
ThreadManager.prototype.shouldPreloadWorkers = function () {
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
};
ThreadManager.prototype.loadWasmModuleToAllWorkers = function () {
var _this_1 = this;
var promises = Array(this.unusedWorkers.length);
var _loop_1 = function (i) {
var worker = this_1.unusedWorkers[i];
if (ENVIRONMENT_IS_NODE)
worker.ref();
promises[i] = this_1.loadWasmModuleToWorker(worker).then(function (w) {
if (ENVIRONMENT_IS_NODE)
worker.unref();
return w;
}, function (e) {
if (ENVIRONMENT_IS_NODE)
worker.unref();
throw e;
});
};
var this_1 = this;
for (var i = 0; i < this.unusedWorkers.length; ++i) {
_loop_1(i);
}
return Promise.all(promises).catch(function (err) {
_this_1.terminateAllThreads();
throw err;
});
};
ThreadManager.prototype.preloadWorkers = function () {
if (this.shouldPreloadWorkers()) {
return this.loadWasmModuleToAllWorkers();
}
return Promise.resolve([]);
};
ThreadManager.prototype.setup = function (wasmModule, wasmMemory) {
this.wasmModule = wasmModule;
this.wasmMemory = wasmMemory;
};
ThreadManager.prototype.markId = function (worker) {
if (worker.__emnapi_tid)
return worker.__emnapi_tid;
var tid = nextWorkerID + 43;
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
this.pthreads[tid] = worker;
worker.__emnapi_tid = tid;
return tid;
};
ThreadManager.prototype.returnWorkerToPool = function (worker) {
var tid = worker.__emnapi_tid;
if (tid !== undefined) {
delete this.pthreads[tid];
}
this.unusedWorkers.push(worker);
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
delete worker.__emnapi_tid;
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
};
ThreadManager.prototype.loadWasmModuleToWorker = function (worker, sab) {
var _this_1 = this;
if (worker.whenLoaded)
return worker.whenLoaded;
var err = this.printErr;
var beforeLoad = this._beforeLoad;
// eslint-disable-next-line @typescript-eslint/no-this-alias
var _this = this;
worker.whenLoaded = new Promise(function (resolve, reject) {
var handleError = function (e) {
var message = 'worker sent an error!';
if (worker.__emnapi_tid !== undefined) {
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
}
if ('message' in e) {
err(message + ' ' + e.message);
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
try {
_this.terminateAllThreads();
}
catch (_) { }
}
}
else {
err(message);
}
reject(e);
throw e;
};
var handleMessage = function (data) {
if (data.__emnapi__) {
var type = data.__emnapi__.type;
var payload = data.__emnapi__.payload;
if (type === 'loaded') {
worker.loaded = true;
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
worker.unref();
}
resolve(worker);
// if (payload.err) {
// err('failed to load in child thread: ' + (payload.err.message || payload.err))
// }
}
else if (type === 'cleanup-thread') {
if (payload.tid in _this_1.pthreads) {
_this_1.cleanThread(worker, payload.tid);
}
}
else if (type === 'spawn-thread') {
_this_1.threadSpawn(payload.startArg, payload.errorOrTid);
}
else if (type === 'terminate-all-threads') {
_this_1.terminateAllThreads();
}
}
};
worker.onmessage = function (e) {
handleMessage(e.data);
_this_1.fireMessageEvent(worker, e);
};
worker.onerror = handleError;
if (ENVIRONMENT_IS_NODE) {
worker.on('message', function (data) {
var _a, _b;
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
data: data
});
});
worker.on('error', function (e) {
var _a, _b;
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
});
worker.on('detachedExit', function () { });
}
if (typeof beforeLoad === 'function') {
beforeLoad(worker);
}
try {
worker.postMessage(createMessage('load', {
wasmModule: _this_1.wasmModule,
wasmMemory: _this_1.wasmMemory,
sab: sab
}));
}
catch (err) {
checkSharedWasmMemory(_this_1.wasmMemory);
throw err;
}
});
return worker.whenLoaded;
};
ThreadManager.prototype.allocateUnusedWorker = function () {
var _onCreateWorker = this._onCreateWorker;
if (typeof _onCreateWorker !== 'function') {
throw new TypeError('`options.onCreateWorker` is not provided');
}
var worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
this.unusedWorkers.push(worker);
return worker;
};
ThreadManager.prototype.getNewWorker = function (sab) {
if (this._reuseWorker) {
if (this.unusedWorkers.length === 0) {
if (this._reuseWorker.strict) {
if (!ENVIRONMENT_IS_NODE) {
var err = this.printErr;
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
return;
}
}
var worker_1 = this.allocateUnusedWorker();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.loadWasmModuleToWorker(worker_1, sab);
}
return this.unusedWorkers.pop();
}
var worker = this.allocateUnusedWorker();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.loadWasmModuleToWorker(worker, sab);
return this.unusedWorkers.pop();
};
ThreadManager.prototype.cleanThread = function (worker, tid, force) {
if (!force && this._reuseWorker) {
this.returnWorkerToPool(worker);
}
else {
delete this.pthreads[tid];
var index = this.runningWorkers.indexOf(worker);
if (index !== -1) {
this.runningWorkers.splice(index, 1);
}
this.terminateWorker(worker);
delete worker.__emnapi_tid;
}
};
ThreadManager.prototype.terminateWorker = function (worker) {
var _this_1 = this;
var _a;
var tid = worker.__emnapi_tid;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
worker.terminate();
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
this.messageEvents.delete(worker);
worker.onmessage = function (e) {
if (e.data.__emnapi__) {
var err = _this_1.printErr;
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
}
};
};
ThreadManager.prototype.terminateAllThreads = function () {
for (var i = 0; i < this.runningWorkers.length; ++i) {
this.terminateWorker(this.runningWorkers[i]);
}
for (var i = 0; i < this.unusedWorkers.length; ++i) {
this.terminateWorker(this.unusedWorkers[i]);
}
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.preparePool();
};
ThreadManager.prototype.addMessageEventListener = function (worker, onMessage) {
var listeners = this.messageEvents.get(worker);
if (!listeners) {
listeners = new Set();
this.messageEvents.set(worker, listeners);
}
listeners.add(onMessage);
return function () {
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
};
};
ThreadManager.prototype.fireMessageEvent = function (worker, e) {
var listeners = this.messageEvents.get(worker);
if (!listeners)
return;
var err = this.printErr;
listeners.forEach(function (listener) {
try {
listener(e);
}
catch (e) {
err(e.stack);
}
});
};
return ThreadManager;
}());
var kIsProxy = Symbol('kIsProxy');
/** @public */
function createInstanceProxy(instance, memory) {
if (instance[kIsProxy])
return instance;
// https://github.com/nodejs/help/issues/4102
var originalExports = instance.exports;
var createHandler = function (target) {
var handlers = [
'apply',
'construct',
'defineProperty',
'deleteProperty',
'get',
'getOwnPropertyDescriptor',
'getPrototypeOf',
'has',
'isExtensible',
'ownKeys',
'preventExtensions',
'set',
'setPrototypeOf'
];
var handler = {};
var _loop_1 = function (i) {
var name_1 = handlers[i];
handler[name_1] = function () {
var args = Array.prototype.slice.call(arguments, 1);
args.unshift(target);
return Reflect[name_1].apply(Reflect, args);
};
};
for (var i = 0; i < handlers.length; i++) {
_loop_1(i);
}
return handler;
};
var handler = createHandler(originalExports);
var _initialize = function () { };
var _start = function () { return 0; };
handler.get = function (_target, p, receiver) {
var _a;
if (p === 'memory') {
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
}
if (p === '_initialize') {
return p in originalExports ? _initialize : undefined;
}
if (p === '_start') {
return p in originalExports ? _start : undefined;
}
return Reflect.get(originalExports, p, receiver);
};
handler.has = function (_target, p) {
if (p === 'memory')
return true;
return Reflect.has(originalExports, p);
};
var exportsProxy = new Proxy(Object.create(null), handler);
return new Proxy(instance, {
get: function (target, p, receiver) {
if (p === 'exports') {
return exportsProxy;
}
if (p === kIsProxy) {
return true;
}
return Reflect.get(target, p, receiver);
}
});
}
var patchedWasiInstances = new WeakMap();
/** @public */
var WASIThreads = /*#__PURE__*/ (function () {
function WASIThreads(options) {
var _this_1 = this;
if (!options) {
throw new TypeError('WASIThreads(): options is not provided');
}
if (!options.wasi) {
throw new TypeError('WASIThreads(): options.wasi is not provided');
}
patchedWasiInstances.set(this, new WeakSet());
var wasi = options.wasi;
patchWasiInstance(this, wasi);
this.wasi = wasi;
if ('childThread' in options) {
this.childThread = Boolean(options.childThread);
}
else {
this.childThread = false;
}
this.PThread = undefined;
if ('threadManager' in options) {
if (typeof options.threadManager === 'function') {
this.PThread = options.threadManager();
}
else {
this.PThread = options.threadManager;
}
}
else {
if (!this.childThread) {
this.PThread = new ThreadManager(options);
this.PThread.init();
}
}
var waitThreadStart = false;
if ('waitThreadStart' in options) {
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
}
var postMessage = getPostMessage(options);
if (this.childThread && typeof postMessage !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMessage;
var wasm64 = Boolean(options.wasm64);
var threadSpawn = function (startArg, errorOrTid) {
var _a;
var EAGAIN = 6;
var isNewABI = errorOrTid !== undefined;
try {
checkSharedWasmMemory(_this_1.wasmMemory);
}
catch (err) {
(_a = _this_1.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
if (isNewABI) {
var struct_1 = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct_1, 0, 1);
Atomics.store(struct_1, 1, EAGAIN);
Atomics.notify(struct_1, 1);
return 1;
}
else {
return -EAGAIN;
}
}
if (!isNewABI) {
var malloc = _this_1.wasmInstance.exports.malloc;
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
if (!errorOrTid) {
return -48; /* ENOMEM */
}
}
var _free = _this_1.wasmInstance.exports.free;
var free = wasm64 ? function (ptr) { _free(BigInt(ptr)); } : _free;
var struct = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, 0);
if (_this_1.childThread) {
postMessage(createMessage('spawn-thread', {
startArg: startArg,
errorOrTid: errorOrTid
}));
Atomics.wait(struct, 1, 0);
var isError = Atomics.load(struct, 0);
var result = Atomics.load(struct, 1);
if (isNewABI) {
return isError;
}
free(errorOrTid);
return isError ? -result : result;
}
var shouldWait = waitThreadStart || (waitThreadStart === 0);
var sab;
if (shouldWait) {
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
Atomics.store(sab, 0, 0);
}
var worker;
var tid;
var PThread = _this_1.PThread;
try {
worker = PThread.getNewWorker(sab);
if (!worker) {
throw new Error('failed to get new worker');
}
tid = PThread.markId(worker);
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
worker.postMessage(createMessage('start', {
tid: tid,
arg: startArg,
sab: sab
}));
if (shouldWait) {
if (typeof waitThreadStart === 'number') {
var waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
if (waitResult === 'timed-out') {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
}
}
else {
Atomics.wait(sab, 0, 0);
}
var r = Atomics.load(sab, 0);
if (r > 1) {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw deserizeErrorFromBuffer(sab.buffer);
}
}
}
catch (e) {
Atomics.store(struct, 0, 1);
Atomics.store(struct, 1, EAGAIN);
Atomics.notify(struct, 1);
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
if (isNewABI) {
return 1;
}
free(errorOrTid);
return -EAGAIN;
}
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, tid);
Atomics.notify(struct, 1);
PThread.runningWorkers.push(worker);
if (!shouldWait) {
worker.whenLoaded.catch(function (err) {
delete worker.whenLoaded;
PThread.cleanThread(worker, tid, true);
throw err;
});
}
if (isNewABI) {
return 0;
}
free(errorOrTid);
return tid;
};
this.threadSpawn = threadSpawn;
if (this.PThread) {
this.PThread.threadSpawn = threadSpawn;
}
}
WASIThreads.prototype.getImportObject = function () {
return {
wasi: {
'thread-spawn': this.threadSpawn
}
};
};
WASIThreads.prototype.setup = function (wasmInstance, wasmModule, wasmMemory) {
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
this.wasmInstance = wasmInstance;
this.wasmMemory = wasmMemory;
if (this.PThread) {
this.PThread.setup(wasmModule, wasmMemory);
}
};
WASIThreads.prototype.preloadWorkers = function () {
if (this.PThread) {
return this.PThread.preloadWorkers();
}
return Promise.resolve([]);
};
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
WASIThreads.prototype.initialize = function (instance, module, memory) {
var exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
var wasi = this.wasi;
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
if (this.childThread) {
wasi.start(instance);
try {
var kStarted = getWasiSymbol(wasi, 'kStarted');
wasi[kStarted] = false;
}
catch (_) { }
}
else {
setupInstance(wasi, instance);
}
}
else {
wasi.initialize(instance);
}
return instance;
};
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
WASIThreads.prototype.start = function (instance, module, memory) {
var exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
var exitCode = this.wasi.start(instance);
return { exitCode: exitCode, instance: instance };
};
WASIThreads.prototype.terminateAllThreads = function () {
var _a;
if (!this.childThread) {
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
}
else {
this.postMessage(createMessage('terminate-all-threads', {}));
}
};
return WASIThreads;
}());
function patchWasiInstance(wasiThreads, wasi) {
var patched = patchedWasiInstances.get(wasiThreads);
if (patched.has(wasi)) {
return;
}
var _this = wasiThreads;
var wasiImport = wasi.wasiImport;
if (wasiImport) {
var proc_exit_1 = wasiImport.proc_exit;
wasiImport.proc_exit = function (code) {
_this.terminateAllThreads();
return proc_exit_1.call(this, code);
};
}
if (!_this.childThread) {
var start_1 = wasi.start;
if (typeof start_1 === 'function') {
wasi.start = function (instance) {
try {
return start_1.call(this, instance);
}
catch (err) {
if (isTrapError(err)) {
_this.terminateAllThreads();
}
throw err;
}
};
}
}
patched.add(wasi);
}
function getWasiSymbol(wasi, description) {
var symbols = Object.getOwnPropertySymbols(wasi);
var selectDescription = function (description) { return function (s) {
if (s.description) {
return s.description === description;
}
return s.toString() === "Symbol(".concat(description, ")");
}; };
if (Array.isArray(description)) {
return description.map(function (d) { return symbols.filter(selectDescription(d))[0]; });
}
return symbols.filter(selectDescription(description))[0];
}
function setupInstance(wasi, instance) {
var _a = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']), kInstance = _a[0], kSetMemory = _a[1];
wasi[kInstance] = instance;
wasi[kSetMemory](instance.exports.memory);
}
/** @public */
var ThreadMessageHandler = /*#__PURE__*/ (function () {
function ThreadMessageHandler(options) {
var postMsg = getPostMessage(options);
if (typeof postMsg !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMsg;
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : function (_type, err) { throw err; };
this.instance = undefined;
// this.module = undefined
this.messagesBeforeLoad = [];
}
/** @virtual */
ThreadMessageHandler.prototype.instantiate = function (data) {
if (typeof this.onLoad === 'function') {
return this.onLoad(data);
}
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
};
/** @virtual */
ThreadMessageHandler.prototype.handle = function (e) {
var _this = this;
var _a;
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
var type = e.data.__emnapi__.type;
var payload_1 = e.data.__emnapi__.payload;
try {
if (type === 'load') {
this._load(payload_1);
}
else if (type === 'start') {
this.handleAfterLoad(e, function () {
_this._start(payload_1);
});
}
}
catch (err) {
this.onError(err, type);
}
}
};
ThreadMessageHandler.prototype._load = function (payload) {
var _this = this;
if (this.instance !== undefined)
return;
var source;
try {
source = this.instantiate(payload);
}
catch (err) {
this._loaded(err, null, payload);
return;
}
var then = source && 'then' in source ? source.then : undefined;
if (typeof then === 'function') {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
then.call(source, function (source) { _this._loaded(null, source, payload); }, function (err) { _this._loaded(err, null, payload); });
}
else {
this._loaded(null, source, payload);
}
};
ThreadMessageHandler.prototype._start = function (payload) {
var wasi_thread_start = this.instance.exports.wasi_thread_start;
if (typeof wasi_thread_start !== 'function') {
var err = new TypeError('wasi_thread_start is not exported');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
var postMessage = this.postMessage;
var tid = payload.tid;
var startArg = payload.arg;
notifyPthreadCreateResult(payload.sab, 1);
try {
wasi_thread_start(tid, startArg);
}
catch (err) {
if (err !== 'unwind') {
throw err;
}
else {
return;
}
}
postMessage(createMessage('cleanup-thread', { tid: tid }));
};
ThreadMessageHandler.prototype._loaded = function (err, source, payload) {
if (err) {
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
if (source == null) {
var err_1 = new TypeError('onLoad should return an object');
notifyPthreadCreateResult(payload.sab, 2, err_1);
throw err_1;
}
var instance = source.instance;
if (!instance) {
var err_2 = new TypeError('onLoad should return an object which includes "instance"');
notifyPthreadCreateResult(payload.sab, 2, err_2);
throw err_2;
}
this.instance = instance;
var postMessage = this.postMessage;
postMessage(createMessage('loaded', {}));
var messages = this.messagesBeforeLoad;
this.messagesBeforeLoad = [];
for (var i = 0; i < messages.length; i++) {
var data = messages[i];
this.handle({ data: data });
}
};
ThreadMessageHandler.prototype.handleAfterLoad = function (e, f) {
if (this.instance !== undefined) {
f.call(this, e);
}
else {
this.messagesBeforeLoad.push(e.data);
}
};
return ThreadMessageHandler;
}());
function notifyPthreadCreateResult(sab, result, error) {
if (sab) {
serizeErrorToBuffer(sab.buffer, result, error);
Atomics.notify(sab, 0);
}
}
export { ThreadManager, ThreadMessageHandler, WASIThreads, createInstanceProxy, isSharedArrayBuffer, isTrapError };
+954
View File
@@ -0,0 +1,954 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.wasiThreads = {}));
})(this, (function (exports) {
var _WebAssembly = typeof WebAssembly !== 'undefined'
? WebAssembly
: typeof WXWebAssembly !== 'undefined'
? WXWebAssembly
: undefined;
var ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
typeof process.versions === 'object' && process.versions !== null &&
typeof process.versions.node === 'string';
function getPostMessage(options) {
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
? options.postMessage
: typeof postMessage === 'function'
? postMessage
: undefined;
}
function serizeErrorToBuffer(sab, code, error) {
var i32array = new Int32Array(sab);
Atomics.store(i32array, 0, code);
if (code > 1 && error) {
var name_1 = error.name;
var message = error.message;
var stack = error.stack;
var nameBuffer = new TextEncoder().encode(name_1);
var messageBuffer = new TextEncoder().encode(message);
var stackBuffer = new TextEncoder().encode(stack);
Atomics.store(i32array, 1, nameBuffer.length);
Atomics.store(i32array, 2, messageBuffer.length);
Atomics.store(i32array, 3, stackBuffer.length);
var buffer = new Uint8Array(sab);
buffer.set(nameBuffer, 16);
buffer.set(messageBuffer, 16 + nameBuffer.length);
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
}
}
function deserizeErrorFromBuffer(sab) {
var _a, _b;
var i32array = new Int32Array(sab);
var status = Atomics.load(i32array, 0);
if (status <= 1) {
return null;
}
var nameLength = Atomics.load(i32array, 1);
var messageLength = Atomics.load(i32array, 2);
var stackLength = Atomics.load(i32array, 3);
var buffer = new Uint8Array(sab);
var nameBuffer = buffer.slice(16, 16 + nameLength);
var messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
var stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
var name = new TextDecoder().decode(nameBuffer);
var message = new TextDecoder().decode(messageBuffer);
var stack = new TextDecoder().decode(stackBuffer);
var ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
var error = new ErrorConstructor(message);
Object.defineProperty(error, 'stack', {
value: stack,
writable: true,
enumerable: false,
configurable: true
});
return error;
}
/** @public */
function isSharedArrayBuffer(value) {
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
}
/** @public */
function isTrapError(e) {
try {
return e instanceof _WebAssembly.RuntimeError;
}
catch (_) {
return false;
}
}
function createMessage(type, payload) {
return {
__emnapi__: {
type: type,
payload: payload
}
};
}
var WASI_THREADS_MAX_TID = 0x1FFFFFFF;
function checkSharedWasmMemory(wasmMemory) {
if (wasmMemory) {
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
throw new Error('Multithread features require shared wasm memory. ' +
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
'then create WebAssembly.Memory with `shared: true` option');
}
}
else {
if (typeof SharedArrayBuffer === 'undefined') {
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
}
}
}
function getReuseWorker(value) {
var _a;
if (typeof value === 'boolean') {
return value ? { size: 0, strict: false } : false;
}
if (typeof value === 'number') {
if (!(value >= 0)) {
throw new RangeError('reuseWorker: size must be a non-negative integer');
}
return { size: value, strict: false };
}
if (!value) {
return false;
}
var size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
var strict = Boolean(value.strict);
if (!(size > 0) && strict) {
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
}
return { size: size, strict: strict };
}
var nextWorkerID = 0;
/** @public */
var ThreadManager = /*#__PURE__*/ (function () {
function ThreadManager(options) {
var _a;
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.wasmModule = null;
this.wasmMemory = null;
this.messageEvents = new WeakMap();
if (!options) {
throw new TypeError('ThreadManager(): options is not provided');
}
if ('childThread' in options) {
this._childThread = Boolean(options.childThread);
}
else {
this._childThread = false;
}
if (this._childThread) {
this._onCreateWorker = undefined;
this._reuseWorker = false;
this._beforeLoad = undefined;
}
else {
this._onCreateWorker = options.onCreateWorker;
this._reuseWorker = getReuseWorker(options.reuseWorker);
this._beforeLoad = options.beforeLoad;
}
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
this.threadSpawn = options.threadSpawn;
}
Object.defineProperty(ThreadManager.prototype, "nextWorkerID", {
get: function () { return nextWorkerID; },
enumerable: false,
configurable: true
});
ThreadManager.prototype.init = function () {
if (!this._childThread) {
this.initMainThread();
}
};
ThreadManager.prototype.initMainThread = function () {
this.preparePool();
};
ThreadManager.prototype.preparePool = function () {
if (this._reuseWorker) {
if (this._reuseWorker.size) {
var pthreadPoolSize = this._reuseWorker.size;
while (pthreadPoolSize--) {
var worker = this.allocateUnusedWorker();
if (ENVIRONMENT_IS_NODE) {
// https://github.com/nodejs/node/issues/53036
worker.once('message', function () { });
worker.unref();
}
}
}
}
};
ThreadManager.prototype.shouldPreloadWorkers = function () {
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
};
ThreadManager.prototype.loadWasmModuleToAllWorkers = function () {
var _this_1 = this;
var promises = Array(this.unusedWorkers.length);
var _loop_1 = function (i) {
var worker = this_1.unusedWorkers[i];
if (ENVIRONMENT_IS_NODE)
worker.ref();
promises[i] = this_1.loadWasmModuleToWorker(worker).then(function (w) {
if (ENVIRONMENT_IS_NODE)
worker.unref();
return w;
}, function (e) {
if (ENVIRONMENT_IS_NODE)
worker.unref();
throw e;
});
};
var this_1 = this;
for (var i = 0; i < this.unusedWorkers.length; ++i) {
_loop_1(i);
}
return Promise.all(promises).catch(function (err) {
_this_1.terminateAllThreads();
throw err;
});
};
ThreadManager.prototype.preloadWorkers = function () {
if (this.shouldPreloadWorkers()) {
return this.loadWasmModuleToAllWorkers();
}
return Promise.resolve([]);
};
ThreadManager.prototype.setup = function (wasmModule, wasmMemory) {
this.wasmModule = wasmModule;
this.wasmMemory = wasmMemory;
};
ThreadManager.prototype.markId = function (worker) {
if (worker.__emnapi_tid)
return worker.__emnapi_tid;
var tid = nextWorkerID + 43;
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
this.pthreads[tid] = worker;
worker.__emnapi_tid = tid;
return tid;
};
ThreadManager.prototype.returnWorkerToPool = function (worker) {
var tid = worker.__emnapi_tid;
if (tid !== undefined) {
delete this.pthreads[tid];
}
this.unusedWorkers.push(worker);
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
delete worker.__emnapi_tid;
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
};
ThreadManager.prototype.loadWasmModuleToWorker = function (worker, sab) {
var _this_1 = this;
if (worker.whenLoaded)
return worker.whenLoaded;
var err = this.printErr;
var beforeLoad = this._beforeLoad;
// eslint-disable-next-line @typescript-eslint/no-this-alias
var _this = this;
worker.whenLoaded = new Promise(function (resolve, reject) {
var handleError = function (e) {
var message = 'worker sent an error!';
if (worker.__emnapi_tid !== undefined) {
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
}
if ('message' in e) {
err(message + ' ' + e.message);
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
try {
_this.terminateAllThreads();
}
catch (_) { }
}
}
else {
err(message);
}
reject(e);
throw e;
};
var handleMessage = function (data) {
if (data.__emnapi__) {
var type = data.__emnapi__.type;
var payload = data.__emnapi__.payload;
if (type === 'loaded') {
worker.loaded = true;
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
worker.unref();
}
resolve(worker);
// if (payload.err) {
// err('failed to load in child thread: ' + (payload.err.message || payload.err))
// }
}
else if (type === 'cleanup-thread') {
if (payload.tid in _this_1.pthreads) {
_this_1.cleanThread(worker, payload.tid);
}
}
else if (type === 'spawn-thread') {
_this_1.threadSpawn(payload.startArg, payload.errorOrTid);
}
else if (type === 'terminate-all-threads') {
_this_1.terminateAllThreads();
}
}
};
worker.onmessage = function (e) {
handleMessage(e.data);
_this_1.fireMessageEvent(worker, e);
};
worker.onerror = handleError;
if (ENVIRONMENT_IS_NODE) {
worker.on('message', function (data) {
var _a, _b;
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
data: data
});
});
worker.on('error', function (e) {
var _a, _b;
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
});
worker.on('detachedExit', function () { });
}
if (typeof beforeLoad === 'function') {
beforeLoad(worker);
}
try {
worker.postMessage(createMessage('load', {
wasmModule: _this_1.wasmModule,
wasmMemory: _this_1.wasmMemory,
sab: sab
}));
}
catch (err) {
checkSharedWasmMemory(_this_1.wasmMemory);
throw err;
}
});
return worker.whenLoaded;
};
ThreadManager.prototype.allocateUnusedWorker = function () {
var _onCreateWorker = this._onCreateWorker;
if (typeof _onCreateWorker !== 'function') {
throw new TypeError('`options.onCreateWorker` is not provided');
}
var worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
this.unusedWorkers.push(worker);
return worker;
};
ThreadManager.prototype.getNewWorker = function (sab) {
if (this._reuseWorker) {
if (this.unusedWorkers.length === 0) {
if (this._reuseWorker.strict) {
if (!ENVIRONMENT_IS_NODE) {
var err = this.printErr;
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
return;
}
}
var worker_1 = this.allocateUnusedWorker();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.loadWasmModuleToWorker(worker_1, sab);
}
return this.unusedWorkers.pop();
}
var worker = this.allocateUnusedWorker();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.loadWasmModuleToWorker(worker, sab);
return this.unusedWorkers.pop();
};
ThreadManager.prototype.cleanThread = function (worker, tid, force) {
if (!force && this._reuseWorker) {
this.returnWorkerToPool(worker);
}
else {
delete this.pthreads[tid];
var index = this.runningWorkers.indexOf(worker);
if (index !== -1) {
this.runningWorkers.splice(index, 1);
}
this.terminateWorker(worker);
delete worker.__emnapi_tid;
}
};
ThreadManager.prototype.terminateWorker = function (worker) {
var _this_1 = this;
var _a;
var tid = worker.__emnapi_tid;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
worker.terminate();
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
this.messageEvents.delete(worker);
worker.onmessage = function (e) {
if (e.data.__emnapi__) {
var err = _this_1.printErr;
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
}
};
};
ThreadManager.prototype.terminateAllThreads = function () {
for (var i = 0; i < this.runningWorkers.length; ++i) {
this.terminateWorker(this.runningWorkers[i]);
}
for (var i = 0; i < this.unusedWorkers.length; ++i) {
this.terminateWorker(this.unusedWorkers[i]);
}
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.preparePool();
};
ThreadManager.prototype.addMessageEventListener = function (worker, onMessage) {
var listeners = this.messageEvents.get(worker);
if (!listeners) {
listeners = new Set();
this.messageEvents.set(worker, listeners);
}
listeners.add(onMessage);
return function () {
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
};
};
ThreadManager.prototype.fireMessageEvent = function (worker, e) {
var listeners = this.messageEvents.get(worker);
if (!listeners)
return;
var err = this.printErr;
listeners.forEach(function (listener) {
try {
listener(e);
}
catch (e) {
err(e.stack);
}
});
};
return ThreadManager;
}());
var kIsProxy = Symbol('kIsProxy');
/** @public */
function createInstanceProxy(instance, memory) {
if (instance[kIsProxy])
return instance;
// https://github.com/nodejs/help/issues/4102
var originalExports = instance.exports;
var createHandler = function (target) {
var handlers = [
'apply',
'construct',
'defineProperty',
'deleteProperty',
'get',
'getOwnPropertyDescriptor',
'getPrototypeOf',
'has',
'isExtensible',
'ownKeys',
'preventExtensions',
'set',
'setPrototypeOf'
];
var handler = {};
var _loop_1 = function (i) {
var name_1 = handlers[i];
handler[name_1] = function () {
var args = Array.prototype.slice.call(arguments, 1);
args.unshift(target);
return Reflect[name_1].apply(Reflect, args);
};
};
for (var i = 0; i < handlers.length; i++) {
_loop_1(i);
}
return handler;
};
var handler = createHandler(originalExports);
var _initialize = function () { };
var _start = function () { return 0; };
handler.get = function (_target, p, receiver) {
var _a;
if (p === 'memory') {
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
}
if (p === '_initialize') {
return p in originalExports ? _initialize : undefined;
}
if (p === '_start') {
return p in originalExports ? _start : undefined;
}
return Reflect.get(originalExports, p, receiver);
};
handler.has = function (_target, p) {
if (p === 'memory')
return true;
return Reflect.has(originalExports, p);
};
var exportsProxy = new Proxy(Object.create(null), handler);
return new Proxy(instance, {
get: function (target, p, receiver) {
if (p === 'exports') {
return exportsProxy;
}
if (p === kIsProxy) {
return true;
}
return Reflect.get(target, p, receiver);
}
});
}
var patchedWasiInstances = new WeakMap();
/** @public */
var WASIThreads = /*#__PURE__*/ (function () {
function WASIThreads(options) {
var _this_1 = this;
if (!options) {
throw new TypeError('WASIThreads(): options is not provided');
}
if (!options.wasi) {
throw new TypeError('WASIThreads(): options.wasi is not provided');
}
patchedWasiInstances.set(this, new WeakSet());
var wasi = options.wasi;
patchWasiInstance(this, wasi);
this.wasi = wasi;
if ('childThread' in options) {
this.childThread = Boolean(options.childThread);
}
else {
this.childThread = false;
}
this.PThread = undefined;
if ('threadManager' in options) {
if (typeof options.threadManager === 'function') {
this.PThread = options.threadManager();
}
else {
this.PThread = options.threadManager;
}
}
else {
if (!this.childThread) {
this.PThread = new ThreadManager(options);
this.PThread.init();
}
}
var waitThreadStart = false;
if ('waitThreadStart' in options) {
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
}
var postMessage = getPostMessage(options);
if (this.childThread && typeof postMessage !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMessage;
var wasm64 = Boolean(options.wasm64);
var threadSpawn = function (startArg, errorOrTid) {
var _a;
var EAGAIN = 6;
var isNewABI = errorOrTid !== undefined;
try {
checkSharedWasmMemory(_this_1.wasmMemory);
}
catch (err) {
(_a = _this_1.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
if (isNewABI) {
var struct_1 = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct_1, 0, 1);
Atomics.store(struct_1, 1, EAGAIN);
Atomics.notify(struct_1, 1);
return 1;
}
else {
return -EAGAIN;
}
}
if (!isNewABI) {
var malloc = _this_1.wasmInstance.exports.malloc;
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
if (!errorOrTid) {
return -48; /* ENOMEM */
}
}
var _free = _this_1.wasmInstance.exports.free;
var free = wasm64 ? function (ptr) { _free(BigInt(ptr)); } : _free;
var struct = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, 0);
if (_this_1.childThread) {
postMessage(createMessage('spawn-thread', {
startArg: startArg,
errorOrTid: errorOrTid
}));
Atomics.wait(struct, 1, 0);
var isError = Atomics.load(struct, 0);
var result = Atomics.load(struct, 1);
if (isNewABI) {
return isError;
}
free(errorOrTid);
return isError ? -result : result;
}
var shouldWait = waitThreadStart || (waitThreadStart === 0);
var sab;
if (shouldWait) {
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
Atomics.store(sab, 0, 0);
}
var worker;
var tid;
var PThread = _this_1.PThread;
try {
worker = PThread.getNewWorker(sab);
if (!worker) {
throw new Error('failed to get new worker');
}
tid = PThread.markId(worker);
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
worker.postMessage(createMessage('start', {
tid: tid,
arg: startArg,
sab: sab
}));
if (shouldWait) {
if (typeof waitThreadStart === 'number') {
var waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
if (waitResult === 'timed-out') {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
}
}
else {
Atomics.wait(sab, 0, 0);
}
var r = Atomics.load(sab, 0);
if (r > 1) {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw deserizeErrorFromBuffer(sab.buffer);
}
}
}
catch (e) {
Atomics.store(struct, 0, 1);
Atomics.store(struct, 1, EAGAIN);
Atomics.notify(struct, 1);
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
if (isNewABI) {
return 1;
}
free(errorOrTid);
return -EAGAIN;
}
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, tid);
Atomics.notify(struct, 1);
PThread.runningWorkers.push(worker);
if (!shouldWait) {
worker.whenLoaded.catch(function (err) {
delete worker.whenLoaded;
PThread.cleanThread(worker, tid, true);
throw err;
});
}
if (isNewABI) {
return 0;
}
free(errorOrTid);
return tid;
};
this.threadSpawn = threadSpawn;
if (this.PThread) {
this.PThread.threadSpawn = threadSpawn;
}
}
WASIThreads.prototype.getImportObject = function () {
return {
wasi: {
'thread-spawn': this.threadSpawn
}
};
};
WASIThreads.prototype.setup = function (wasmInstance, wasmModule, wasmMemory) {
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
this.wasmInstance = wasmInstance;
this.wasmMemory = wasmMemory;
if (this.PThread) {
this.PThread.setup(wasmModule, wasmMemory);
}
};
WASIThreads.prototype.preloadWorkers = function () {
if (this.PThread) {
return this.PThread.preloadWorkers();
}
return Promise.resolve([]);
};
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
WASIThreads.prototype.initialize = function (instance, module, memory) {
var exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
var wasi = this.wasi;
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
if (this.childThread) {
wasi.start(instance);
try {
var kStarted = getWasiSymbol(wasi, 'kStarted');
wasi[kStarted] = false;
}
catch (_) { }
}
else {
setupInstance(wasi, instance);
}
}
else {
wasi.initialize(instance);
}
return instance;
};
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
WASIThreads.prototype.start = function (instance, module, memory) {
var exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
var exitCode = this.wasi.start(instance);
return { exitCode: exitCode, instance: instance };
};
WASIThreads.prototype.terminateAllThreads = function () {
var _a;
if (!this.childThread) {
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
}
else {
this.postMessage(createMessage('terminate-all-threads', {}));
}
};
return WASIThreads;
}());
function patchWasiInstance(wasiThreads, wasi) {
var patched = patchedWasiInstances.get(wasiThreads);
if (patched.has(wasi)) {
return;
}
var _this = wasiThreads;
var wasiImport = wasi.wasiImport;
if (wasiImport) {
var proc_exit_1 = wasiImport.proc_exit;
wasiImport.proc_exit = function (code) {
_this.terminateAllThreads();
return proc_exit_1.call(this, code);
};
}
if (!_this.childThread) {
var start_1 = wasi.start;
if (typeof start_1 === 'function') {
wasi.start = function (instance) {
try {
return start_1.call(this, instance);
}
catch (err) {
if (isTrapError(err)) {
_this.terminateAllThreads();
}
throw err;
}
};
}
}
patched.add(wasi);
}
function getWasiSymbol(wasi, description) {
var symbols = Object.getOwnPropertySymbols(wasi);
var selectDescription = function (description) { return function (s) {
if (s.description) {
return s.description === description;
}
return s.toString() === "Symbol(".concat(description, ")");
}; };
if (Array.isArray(description)) {
return description.map(function (d) { return symbols.filter(selectDescription(d))[0]; });
}
return symbols.filter(selectDescription(description))[0];
}
function setupInstance(wasi, instance) {
var _a = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']), kInstance = _a[0], kSetMemory = _a[1];
wasi[kInstance] = instance;
wasi[kSetMemory](instance.exports.memory);
}
/** @public */
var ThreadMessageHandler = /*#__PURE__*/ (function () {
function ThreadMessageHandler(options) {
var postMsg = getPostMessage(options);
if (typeof postMsg !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMsg;
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : function (_type, err) { throw err; };
this.instance = undefined;
// this.module = undefined
this.messagesBeforeLoad = [];
}
/** @virtual */
ThreadMessageHandler.prototype.instantiate = function (data) {
if (typeof this.onLoad === 'function') {
return this.onLoad(data);
}
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
};
/** @virtual */
ThreadMessageHandler.prototype.handle = function (e) {
var _this = this;
var _a;
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
var type = e.data.__emnapi__.type;
var payload_1 = e.data.__emnapi__.payload;
try {
if (type === 'load') {
this._load(payload_1);
}
else if (type === 'start') {
this.handleAfterLoad(e, function () {
_this._start(payload_1);
});
}
}
catch (err) {
this.onError(err, type);
}
}
};
ThreadMessageHandler.prototype._load = function (payload) {
var _this = this;
if (this.instance !== undefined)
return;
var source;
try {
source = this.instantiate(payload);
}
catch (err) {
this._loaded(err, null, payload);
return;
}
var then = source && 'then' in source ? source.then : undefined;
if (typeof then === 'function') {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
then.call(source, function (source) { _this._loaded(null, source, payload); }, function (err) { _this._loaded(err, null, payload); });
}
else {
this._loaded(null, source, payload);
}
};
ThreadMessageHandler.prototype._start = function (payload) {
var wasi_thread_start = this.instance.exports.wasi_thread_start;
if (typeof wasi_thread_start !== 'function') {
var err = new TypeError('wasi_thread_start is not exported');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
var postMessage = this.postMessage;
var tid = payload.tid;
var startArg = payload.arg;
notifyPthreadCreateResult(payload.sab, 1);
try {
wasi_thread_start(tid, startArg);
}
catch (err) {
if (err !== 'unwind') {
throw err;
}
else {
return;
}
}
postMessage(createMessage('cleanup-thread', { tid: tid }));
};
ThreadMessageHandler.prototype._loaded = function (err, source, payload) {
if (err) {
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
if (source == null) {
var err_1 = new TypeError('onLoad should return an object');
notifyPthreadCreateResult(payload.sab, 2, err_1);
throw err_1;
}
var instance = source.instance;
if (!instance) {
var err_2 = new TypeError('onLoad should return an object which includes "instance"');
notifyPthreadCreateResult(payload.sab, 2, err_2);
throw err_2;
}
this.instance = instance;
var postMessage = this.postMessage;
postMessage(createMessage('loaded', {}));
var messages = this.messagesBeforeLoad;
this.messagesBeforeLoad = [];
for (var i = 0; i < messages.length; i++) {
var data = messages[i];
this.handle({ data: data });
}
};
ThreadMessageHandler.prototype.handleAfterLoad = function (e, f) {
if (this.instance !== undefined) {
f.call(this, e);
}
else {
this.messagesBeforeLoad.push(e.data);
}
};
return ThreadMessageHandler;
}());
function notifyPthreadCreateResult(sab, result, error) {
if (sab) {
serizeErrorToBuffer(sab.buffer, result, error);
Atomics.notify(sab, 0);
}
}
exports.ThreadManager = ThreadManager;
exports.ThreadMessageHandler = ThreadMessageHandler;
exports.WASIThreads = WASIThreads;
exports.createInstanceProxy = createInstanceProxy;
exports.isSharedArrayBuffer = isSharedArrayBuffer;
exports.isTrapError = isTrapError;
}));
+272
View File
@@ -0,0 +1,272 @@
/// <reference types="node" />
import type { Worker as Worker_2 } from 'worker_threads';
/** @public */
export declare interface BaseOptions {
wasi: WASIInstance;
version?: 'preview1';
wasm64?: boolean;
}
/** @public */
export declare interface ChildThreadOptions extends BaseOptions {
childThread: true;
postMessage?: (data: any) => void;
}
/** @public */
export declare interface CleanupThreadPayload {
tid: number;
}
/** @public */
export declare interface CommandInfo<T extends CommandType> {
type: T;
payload: CommandPayloadMap[T];
}
/** @public */
export declare interface CommandPayloadMap {
load: LoadPayload;
loaded: LoadedPayload;
start: StartPayload;
'cleanup-thread': CleanupThreadPayload;
'terminate-all-threads': TerminateAllThreadsPayload;
'spawn-thread': SpawnThreadPayload;
}
/** @public */
export declare type CommandType = keyof CommandPayloadMap;
/** @public */
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
/** @public */
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
/** @public */
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
/** @public */
export declare interface LoadedPayload {
}
/** @public */
export declare interface LoadPayload {
wasmModule: WebAssembly.Module;
wasmMemory: WebAssembly.Memory;
sab?: Int32Array;
}
/** @public */
export declare interface MainThreadBaseOptions extends BaseOptions {
waitThreadStart?: boolean | number;
}
/** @public */
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
/** @public */
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
}
/** @public */
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
threadManager?: ThreadManager | (() => ThreadManager);
}
/** @public */
export declare interface MessageEventData<T extends CommandType> {
__emnapi__: CommandInfo<T>;
}
/** @public */
export declare interface ReuseWorkerOptions {
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
*/
size: number;
/**
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
*/
strict?: boolean;
}
/** @public */
export declare interface SpawnThreadPayload {
startArg: number;
errorOrTid: number;
}
/** @public */
export declare interface StartPayload {
tid: number;
arg: number;
sab?: Int32Array;
}
/** @public */
export declare interface StartResult {
exitCode: number;
instance: WebAssembly.Instance;
}
/** @public */
export declare interface TerminateAllThreadsPayload {
}
/** @public */
export declare class ThreadManager {
unusedWorkers: WorkerLike[];
runningWorkers: WorkerLike[];
pthreads: Record<number, WorkerLike>;
get nextWorkerID(): number;
wasmModule: WebAssembly.Module | null;
wasmMemory: WebAssembly.Memory | null;
private readonly messageEvents;
private readonly _childThread;
private readonly _onCreateWorker;
private readonly _reuseWorker;
private readonly _beforeLoad?;
/* Excluded from this release type: printErr */
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
constructor(options: ThreadManagerOptions);
init(): void;
initMainThread(): void;
private preparePool;
shouldPreloadWorkers(): boolean;
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
preloadWorkers(): Promise<WorkerLike[]>;
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
markId(worker: WorkerLike): number;
returnWorkerToPool(worker: WorkerLike): void;
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
allocateUnusedWorker(): WorkerLike;
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
terminateWorker(worker: WorkerLike): void;
terminateAllThreads(): void;
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
}
/** @public */
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
/** @public */
export declare interface ThreadManagerOptionsBase {
printErr?: (message: string) => void;
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
childThread: true;
}
/** @public */
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
beforeLoad?: (worker: WorkerLike) => any;
reuseWorker?: boolean | number | ReuseWorkerOptions;
onCreateWorker: WorkerFactory;
childThread?: false;
}
/** @public */
export declare class ThreadMessageHandler {
protected instance: WebAssembly.Instance | undefined;
private messagesBeforeLoad;
protected postMessage: (message: any) => void;
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
protected onError: (error: Error, type: WorkerMessageType) => void;
constructor(options?: ThreadMessageHandlerOptions);
/** @virtual */
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
/** @virtual */
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
private _load;
private _start;
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
}
/** @public */
export declare interface ThreadMessageHandlerOptions {
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
onError?: (error: Error, type: WorkerMessageType) => void;
postMessage?: (message: any) => void;
}
/** @public */
export declare interface WASIInstance {
readonly wasiImport?: Record<string, any>;
initialize(instance: object): void;
start(instance: object): number;
getImportObject?(): any;
}
/** @public */
export declare class WASIThreads {
PThread: ThreadManager | undefined;
private wasmMemory;
private wasmInstance;
private readonly threadSpawn;
readonly childThread: boolean;
private readonly postMessage;
readonly wasi: WASIInstance;
constructor(options: WASIThreadsOptions);
getImportObject(): {
wasi: WASIThreadsImports;
};
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
preloadWorkers(): Promise<WorkerLike[]>;
/**
* It's ok to call this method to a WASI command module.
*
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
*
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
*/
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
/**
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
* ```js
* this.initialize(instance, module, memory)
* this.wasi.start(instance)
* ```
*/
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
terminateAllThreads(): void;
}
/** @public */
export declare interface WASIThreadsImports {
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
}
/** @public */
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
/** @public */
export declare type WorkerFactory = (ctx: {
type: string;
name: string;
}) => WorkerLike;
/** @public */
export declare type WorkerLike = (Worker | Worker_2) & {
whenLoaded?: Promise<WorkerLike>;
loaded?: boolean;
__emnapi_tid?: number;
};
/** @public */
export declare interface WorkerMessageEvent<T = any> {
data: T;
}
/** @public */
export declare type WorkerMessageType = 'load' | 'start';
export { }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+889
View File
@@ -0,0 +1,889 @@
const _WebAssembly = typeof WebAssembly !== 'undefined'
? WebAssembly
: typeof WXWebAssembly !== 'undefined'
? WXWebAssembly
: undefined;
const ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
typeof process.versions === 'object' && process.versions !== null &&
typeof process.versions.node === 'string';
function getPostMessage(options) {
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
? options.postMessage
: typeof postMessage === 'function'
? postMessage
: undefined;
}
function serizeErrorToBuffer(sab, code, error) {
const i32array = new Int32Array(sab);
Atomics.store(i32array, 0, code);
if (code > 1 && error) {
const name = error.name;
const message = error.message;
const stack = error.stack;
const nameBuffer = new TextEncoder().encode(name);
const messageBuffer = new TextEncoder().encode(message);
const stackBuffer = new TextEncoder().encode(stack);
Atomics.store(i32array, 1, nameBuffer.length);
Atomics.store(i32array, 2, messageBuffer.length);
Atomics.store(i32array, 3, stackBuffer.length);
const buffer = new Uint8Array(sab);
buffer.set(nameBuffer, 16);
buffer.set(messageBuffer, 16 + nameBuffer.length);
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
}
}
function deserizeErrorFromBuffer(sab) {
var _a, _b;
const i32array = new Int32Array(sab);
const status = Atomics.load(i32array, 0);
if (status <= 1) {
return null;
}
const nameLength = Atomics.load(i32array, 1);
const messageLength = Atomics.load(i32array, 2);
const stackLength = Atomics.load(i32array, 3);
const buffer = new Uint8Array(sab);
const nameBuffer = buffer.slice(16, 16 + nameLength);
const messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
const stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
const name = new TextDecoder().decode(nameBuffer);
const message = new TextDecoder().decode(messageBuffer);
const stack = new TextDecoder().decode(stackBuffer);
const ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
const error = new ErrorConstructor(message);
Object.defineProperty(error, 'stack', {
value: stack,
writable: true,
enumerable: false,
configurable: true
});
return error;
}
function isSharedArrayBuffer(value) {
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
}
function isTrapError(e) {
try {
return e instanceof _WebAssembly.RuntimeError;
}
catch (_) {
return false;
}
}
function createMessage(type, payload) {
return {
__emnapi__: {
type,
payload
}
};
}
const WASI_THREADS_MAX_TID = 0x1FFFFFFF;
function checkSharedWasmMemory(wasmMemory) {
if (wasmMemory) {
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
throw new Error('Multithread features require shared wasm memory. ' +
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
'then create WebAssembly.Memory with `shared: true` option');
}
}
else {
if (typeof SharedArrayBuffer === 'undefined') {
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
}
}
}
function getReuseWorker(value) {
var _a;
if (typeof value === 'boolean') {
return value ? { size: 0, strict: false } : false;
}
if (typeof value === 'number') {
if (!(value >= 0)) {
throw new RangeError('reuseWorker: size must be a non-negative integer');
}
return { size: value, strict: false };
}
if (!value) {
return false;
}
const size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
const strict = Boolean(value.strict);
if (!(size > 0) && strict) {
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
}
return { size, strict };
}
let nextWorkerID = 0;
class ThreadManager {
get nextWorkerID() { return nextWorkerID; }
constructor(options) {
var _a;
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.wasmModule = null;
this.wasmMemory = null;
this.messageEvents = new WeakMap();
if (!options) {
throw new TypeError('ThreadManager(): options is not provided');
}
if ('childThread' in options) {
this._childThread = Boolean(options.childThread);
}
else {
this._childThread = false;
}
if (this._childThread) {
this._onCreateWorker = undefined;
this._reuseWorker = false;
this._beforeLoad = undefined;
}
else {
this._onCreateWorker = options.onCreateWorker;
this._reuseWorker = getReuseWorker(options.reuseWorker);
this._beforeLoad = options.beforeLoad;
}
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
this.threadSpawn = options.threadSpawn;
}
init() {
if (!this._childThread) {
this.initMainThread();
}
}
initMainThread() {
this.preparePool();
}
preparePool() {
if (this._reuseWorker) {
if (this._reuseWorker.size) {
let pthreadPoolSize = this._reuseWorker.size;
while (pthreadPoolSize--) {
const worker = this.allocateUnusedWorker();
if (ENVIRONMENT_IS_NODE) {
worker.once('message', () => { });
worker.unref();
}
}
}
}
}
shouldPreloadWorkers() {
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
}
loadWasmModuleToAllWorkers() {
const promises = Array(this.unusedWorkers.length);
for (let i = 0; i < this.unusedWorkers.length; ++i) {
const worker = this.unusedWorkers[i];
if (ENVIRONMENT_IS_NODE)
worker.ref();
promises[i] = this.loadWasmModuleToWorker(worker).then((w) => {
if (ENVIRONMENT_IS_NODE)
worker.unref();
return w;
}, (e) => {
if (ENVIRONMENT_IS_NODE)
worker.unref();
throw e;
});
}
return Promise.all(promises).catch((err) => {
this.terminateAllThreads();
throw err;
});
}
preloadWorkers() {
if (this.shouldPreloadWorkers()) {
return this.loadWasmModuleToAllWorkers();
}
return Promise.resolve([]);
}
setup(wasmModule, wasmMemory) {
this.wasmModule = wasmModule;
this.wasmMemory = wasmMemory;
}
markId(worker) {
if (worker.__emnapi_tid)
return worker.__emnapi_tid;
const tid = nextWorkerID + 43;
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
this.pthreads[tid] = worker;
worker.__emnapi_tid = tid;
return tid;
}
returnWorkerToPool(worker) {
var tid = worker.__emnapi_tid;
if (tid !== undefined) {
delete this.pthreads[tid];
}
this.unusedWorkers.push(worker);
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
delete worker.__emnapi_tid;
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
}
loadWasmModuleToWorker(worker, sab) {
if (worker.whenLoaded)
return worker.whenLoaded;
const err = this.printErr;
const beforeLoad = this._beforeLoad;
const _this = this;
worker.whenLoaded = new Promise((resolve, reject) => {
const handleError = function (e) {
let message = 'worker sent an error!';
if (worker.__emnapi_tid !== undefined) {
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
}
if ('message' in e) {
err(message + ' ' + e.message);
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
try {
_this.terminateAllThreads();
}
catch (_) { }
}
}
else {
err(message);
}
reject(e);
throw e;
};
const handleMessage = (data) => {
if (data.__emnapi__) {
const type = data.__emnapi__.type;
const payload = data.__emnapi__.payload;
if (type === 'loaded') {
worker.loaded = true;
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
worker.unref();
}
resolve(worker);
}
else if (type === 'cleanup-thread') {
if (payload.tid in this.pthreads) {
this.cleanThread(worker, payload.tid);
}
}
else if (type === 'spawn-thread') {
this.threadSpawn(payload.startArg, payload.errorOrTid);
}
else if (type === 'terminate-all-threads') {
this.terminateAllThreads();
}
}
};
worker.onmessage = (e) => {
handleMessage(e.data);
this.fireMessageEvent(worker, e);
};
worker.onerror = handleError;
if (ENVIRONMENT_IS_NODE) {
worker.on('message', function (data) {
var _a, _b;
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
data
});
});
worker.on('error', function (e) {
var _a, _b;
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
});
worker.on('detachedExit', function () { });
}
if (typeof beforeLoad === 'function') {
beforeLoad(worker);
}
try {
worker.postMessage(createMessage('load', {
wasmModule: this.wasmModule,
wasmMemory: this.wasmMemory,
sab
}));
}
catch (err) {
checkSharedWasmMemory(this.wasmMemory);
throw err;
}
});
return worker.whenLoaded;
}
allocateUnusedWorker() {
const _onCreateWorker = this._onCreateWorker;
if (typeof _onCreateWorker !== 'function') {
throw new TypeError('`options.onCreateWorker` is not provided');
}
const worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
this.unusedWorkers.push(worker);
return worker;
}
getNewWorker(sab) {
if (this._reuseWorker) {
if (this.unusedWorkers.length === 0) {
if (this._reuseWorker.strict) {
if (!ENVIRONMENT_IS_NODE) {
const err = this.printErr;
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
return;
}
}
const worker = this.allocateUnusedWorker();
this.loadWasmModuleToWorker(worker, sab);
}
return this.unusedWorkers.pop();
}
const worker = this.allocateUnusedWorker();
this.loadWasmModuleToWorker(worker, sab);
return this.unusedWorkers.pop();
}
cleanThread(worker, tid, force) {
if (!force && this._reuseWorker) {
this.returnWorkerToPool(worker);
}
else {
delete this.pthreads[tid];
const index = this.runningWorkers.indexOf(worker);
if (index !== -1) {
this.runningWorkers.splice(index, 1);
}
this.terminateWorker(worker);
delete worker.__emnapi_tid;
}
}
terminateWorker(worker) {
var _a;
const tid = worker.__emnapi_tid;
worker.terminate();
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
this.messageEvents.delete(worker);
worker.onmessage = (e) => {
if (e.data.__emnapi__) {
const err = this.printErr;
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
}
};
}
terminateAllThreads() {
for (let i = 0; i < this.runningWorkers.length; ++i) {
this.terminateWorker(this.runningWorkers[i]);
}
for (let i = 0; i < this.unusedWorkers.length; ++i) {
this.terminateWorker(this.unusedWorkers[i]);
}
this.unusedWorkers = [];
this.runningWorkers = [];
this.pthreads = Object.create(null);
this.preparePool();
}
addMessageEventListener(worker, onMessage) {
let listeners = this.messageEvents.get(worker);
if (!listeners) {
listeners = new Set();
this.messageEvents.set(worker, listeners);
}
listeners.add(onMessage);
return () => {
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
};
}
fireMessageEvent(worker, e) {
const listeners = this.messageEvents.get(worker);
if (!listeners)
return;
const err = this.printErr;
listeners.forEach((listener) => {
try {
listener(e);
}
catch (e) {
err(e.stack);
}
});
}
}
const kIsProxy = Symbol('kIsProxy');
function createInstanceProxy(instance, memory) {
if (instance[kIsProxy])
return instance;
const originalExports = instance.exports;
const createHandler = function (target) {
const handlers = [
'apply',
'construct',
'defineProperty',
'deleteProperty',
'get',
'getOwnPropertyDescriptor',
'getPrototypeOf',
'has',
'isExtensible',
'ownKeys',
'preventExtensions',
'set',
'setPrototypeOf'
];
const handler = {};
for (let i = 0; i < handlers.length; i++) {
const name = handlers[i];
handler[name] = function () {
const args = Array.prototype.slice.call(arguments, 1);
args.unshift(target);
return Reflect[name].apply(Reflect, args);
};
}
return handler;
};
const handler = createHandler(originalExports);
const _initialize = () => { };
const _start = () => 0;
handler.get = function (_target, p, receiver) {
var _a;
if (p === 'memory') {
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
}
if (p === '_initialize') {
return p in originalExports ? _initialize : undefined;
}
if (p === '_start') {
return p in originalExports ? _start : undefined;
}
return Reflect.get(originalExports, p, receiver);
};
handler.has = function (_target, p) {
if (p === 'memory')
return true;
return Reflect.has(originalExports, p);
};
const exportsProxy = new Proxy(Object.create(null), handler);
return new Proxy(instance, {
get(target, p, receiver) {
if (p === 'exports') {
return exportsProxy;
}
if (p === kIsProxy) {
return true;
}
return Reflect.get(target, p, receiver);
}
});
}
const patchedWasiInstances = new WeakMap();
class WASIThreads {
constructor(options) {
if (!options) {
throw new TypeError('WASIThreads(): options is not provided');
}
if (!options.wasi) {
throw new TypeError('WASIThreads(): options.wasi is not provided');
}
patchedWasiInstances.set(this, new WeakSet());
const wasi = options.wasi;
patchWasiInstance(this, wasi);
this.wasi = wasi;
if ('childThread' in options) {
this.childThread = Boolean(options.childThread);
}
else {
this.childThread = false;
}
this.PThread = undefined;
if ('threadManager' in options) {
if (typeof options.threadManager === 'function') {
this.PThread = options.threadManager();
}
else {
this.PThread = options.threadManager;
}
}
else {
if (!this.childThread) {
this.PThread = new ThreadManager(options);
this.PThread.init();
}
}
let waitThreadStart = false;
if ('waitThreadStart' in options) {
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
}
const postMessage = getPostMessage(options);
if (this.childThread && typeof postMessage !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMessage;
const wasm64 = Boolean(options.wasm64);
const threadSpawn = (startArg, errorOrTid) => {
var _a;
const EAGAIN = 6;
const isNewABI = errorOrTid !== undefined;
try {
checkSharedWasmMemory(this.wasmMemory);
}
catch (err) {
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
if (isNewABI) {
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct, 0, 1);
Atomics.store(struct, 1, EAGAIN);
Atomics.notify(struct, 1);
return 1;
}
else {
return -EAGAIN;
}
}
if (!isNewABI) {
const malloc = this.wasmInstance.exports.malloc;
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
if (!errorOrTid) {
return -48;
}
}
const _free = this.wasmInstance.exports.free;
const free = wasm64 ? (ptr) => { _free(BigInt(ptr)); } : _free;
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, 0);
if (this.childThread) {
postMessage(createMessage('spawn-thread', {
startArg,
errorOrTid: errorOrTid
}));
Atomics.wait(struct, 1, 0);
const isError = Atomics.load(struct, 0);
const result = Atomics.load(struct, 1);
if (isNewABI) {
return isError;
}
free(errorOrTid);
return isError ? -result : result;
}
const shouldWait = waitThreadStart || (waitThreadStart === 0);
let sab;
if (shouldWait) {
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
Atomics.store(sab, 0, 0);
}
let worker;
let tid;
const PThread = this.PThread;
try {
worker = PThread.getNewWorker(sab);
if (!worker) {
throw new Error('failed to get new worker');
}
tid = PThread.markId(worker);
if (ENVIRONMENT_IS_NODE) {
worker.unref();
}
worker.postMessage(createMessage('start', {
tid,
arg: startArg,
sab
}));
if (shouldWait) {
if (typeof waitThreadStart === 'number') {
const waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
if (waitResult === 'timed-out') {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
}
}
else {
Atomics.wait(sab, 0, 0);
}
const r = Atomics.load(sab, 0);
if (r > 1) {
try {
PThread.cleanThread(worker, tid, true);
}
catch (_) { }
throw deserizeErrorFromBuffer(sab.buffer);
}
}
}
catch (e) {
Atomics.store(struct, 0, 1);
Atomics.store(struct, 1, EAGAIN);
Atomics.notify(struct, 1);
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
if (isNewABI) {
return 1;
}
free(errorOrTid);
return -EAGAIN;
}
Atomics.store(struct, 0, 0);
Atomics.store(struct, 1, tid);
Atomics.notify(struct, 1);
PThread.runningWorkers.push(worker);
if (!shouldWait) {
worker.whenLoaded.catch((err) => {
delete worker.whenLoaded;
PThread.cleanThread(worker, tid, true);
throw err;
});
}
if (isNewABI) {
return 0;
}
free(errorOrTid);
return tid;
};
this.threadSpawn = threadSpawn;
if (this.PThread) {
this.PThread.threadSpawn = threadSpawn;
}
}
getImportObject() {
return {
wasi: {
'thread-spawn': this.threadSpawn
}
};
}
setup(wasmInstance, wasmModule, wasmMemory) {
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
this.wasmInstance = wasmInstance;
this.wasmMemory = wasmMemory;
if (this.PThread) {
this.PThread.setup(wasmModule, wasmMemory);
}
}
preloadWorkers() {
if (this.PThread) {
return this.PThread.preloadWorkers();
}
return Promise.resolve([]);
}
initialize(instance, module, memory) {
const exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
const wasi = this.wasi;
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
if (this.childThread) {
wasi.start(instance);
try {
const kStarted = getWasiSymbol(wasi, 'kStarted');
wasi[kStarted] = false;
}
catch (_) { }
}
else {
setupInstance(wasi, instance);
}
}
else {
wasi.initialize(instance);
}
return instance;
}
start(instance, module, memory) {
const exports$1 = instance.exports;
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
if (this.childThread) {
instance = createInstanceProxy(instance, memory);
}
this.setup(instance, module, memory);
const exitCode = this.wasi.start(instance);
return { exitCode, instance };
}
terminateAllThreads() {
var _a;
if (!this.childThread) {
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
}
else {
this.postMessage(createMessage('terminate-all-threads', {}));
}
}
}
function patchWasiInstance(wasiThreads, wasi) {
const patched = patchedWasiInstances.get(wasiThreads);
if (patched.has(wasi)) {
return;
}
const _this = wasiThreads;
const wasiImport = wasi.wasiImport;
if (wasiImport) {
const proc_exit = wasiImport.proc_exit;
wasiImport.proc_exit = function (code) {
_this.terminateAllThreads();
return proc_exit.call(this, code);
};
}
if (!_this.childThread) {
const start = wasi.start;
if (typeof start === 'function') {
wasi.start = function (instance) {
try {
return start.call(this, instance);
}
catch (err) {
if (isTrapError(err)) {
_this.terminateAllThreads();
}
throw err;
}
};
}
}
patched.add(wasi);
}
function getWasiSymbol(wasi, description) {
const symbols = Object.getOwnPropertySymbols(wasi);
const selectDescription = (description) => (s) => {
if (s.description) {
return s.description === description;
}
return s.toString() === `Symbol(${description})`;
};
if (Array.isArray(description)) {
return description.map(d => symbols.filter(selectDescription(d))[0]);
}
return symbols.filter(selectDescription(description))[0];
}
function setupInstance(wasi, instance) {
const [kInstance, kSetMemory] = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']);
wasi[kInstance] = instance;
wasi[kSetMemory](instance.exports.memory);
}
class ThreadMessageHandler {
constructor(options) {
const postMsg = getPostMessage(options);
if (typeof postMsg !== 'function') {
throw new TypeError('options.postMessage is not a function');
}
this.postMessage = postMsg;
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : (_type, err) => { throw err; };
this.instance = undefined;
this.messagesBeforeLoad = [];
}
instantiate(data) {
if (typeof this.onLoad === 'function') {
return this.onLoad(data);
}
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
}
handle(e) {
var _a;
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
const type = e.data.__emnapi__.type;
const payload = e.data.__emnapi__.payload;
try {
if (type === 'load') {
this._load(payload);
}
else if (type === 'start') {
this.handleAfterLoad(e, () => {
this._start(payload);
});
}
}
catch (err) {
this.onError(err, type);
}
}
}
_load(payload) {
if (this.instance !== undefined)
return;
let source;
try {
source = this.instantiate(payload);
}
catch (err) {
this._loaded(err, null, payload);
return;
}
const then = source && 'then' in source ? source.then : undefined;
if (typeof then === 'function') {
then.call(source, (source) => { this._loaded(null, source, payload); }, (err) => { this._loaded(err, null, payload); });
}
else {
this._loaded(null, source, payload);
}
}
_start(payload) {
const wasi_thread_start = this.instance.exports.wasi_thread_start;
if (typeof wasi_thread_start !== 'function') {
const err = new TypeError('wasi_thread_start is not exported');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
const postMessage = this.postMessage;
const tid = payload.tid;
const startArg = payload.arg;
notifyPthreadCreateResult(payload.sab, 1);
try {
wasi_thread_start(tid, startArg);
}
catch (err) {
if (err !== 'unwind') {
throw err;
}
else {
return;
}
}
postMessage(createMessage('cleanup-thread', { tid }));
}
_loaded(err, source, payload) {
if (err) {
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
if (source == null) {
const err = new TypeError('onLoad should return an object');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
const instance = source.instance;
if (!instance) {
const err = new TypeError('onLoad should return an object which includes "instance"');
notifyPthreadCreateResult(payload.sab, 2, err);
throw err;
}
this.instance = instance;
const postMessage = this.postMessage;
postMessage(createMessage('loaded', {}));
const messages = this.messagesBeforeLoad;
this.messagesBeforeLoad = [];
for (let i = 0; i < messages.length; i++) {
const data = messages[i];
this.handle({ data });
}
}
handleAfterLoad(e, f) {
if (this.instance !== undefined) {
f.call(this, e);
}
else {
this.messagesBeforeLoad.push(e.data);
}
}
}
function notifyPthreadCreateResult(sab, result, error) {
if (sab) {
serizeErrorToBuffer(sab.buffer, result, error);
Atomics.notify(sab, 0);
}
}
export { ThreadManager, ThreadMessageHandler, WASIThreads, createInstanceProxy, isSharedArrayBuffer, isTrapError };
+5
View File
@@ -0,0 +1,5 @@
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production') {
module.exports = require('./dist/wasi-threads.cjs.min.js')
} else {
module.exports = require('./dist/wasi-threads.cjs.js')
}
+50
View File
@@ -0,0 +1,50 @@
{
"name": "@emnapi/wasi-threads",
"version": "1.2.1",
"description": "WASI threads proposal implementation in JavaScript",
"main": "index.js",
"module": "./dist/wasi-threads.esm-bundler.js",
"types": "./dist/wasi-threads.d.ts",
"sideEffects": false,
"exports": {
".": {
"types": {
"module": "./dist/wasi-threads.d.ts",
"import": "./dist/wasi-threads.d.mts",
"default": "./dist/wasi-threads.d.ts"
},
"module": "./dist/wasi-threads.esm-bundler.js",
"import": "./dist/wasi-threads.mjs",
"default": "./index.js"
},
"./dist/wasi-threads.cjs.min": {
"types": "./dist/wasi-threads.d.ts",
"default": "./dist/wasi-threads.cjs.min.js"
},
"./dist/wasi-threads.min.mjs": {
"types": "./dist/wasi-threads.d.mts",
"default": "./dist/wasi-threads.min.mjs"
}
},
"dependencies": {
"tslib": "^2.4.0"
},
"scripts": {
"build": "node ./script/build.js",
"build:test": "node ./test/build.js",
"test": "node ./test/index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/toyobayashi/emnapi.git"
},
"author": "toyobayashi",
"license": "MIT",
"bugs": {
"url": "https://github.com/toyobayashi/emnapi/issues"
},
"homepage": "https://github.com/toyobayashi/emnapi#readme",
"publishConfig": {
"access": "public"
}
}
+19
View File
@@ -0,0 +1,19 @@
Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+227
View File
@@ -0,0 +1,227 @@
# @jridgewell/gen-mapping
> Generate source maps
`gen-mapping` allows you to generate a source map during transpilation or minification.
With a source map, you're able to trace the original location in the source file, either in Chrome's
DevTools or using a library like [`@jridgewell/trace-mapping`][trace-mapping].
You may already be familiar with the [`source-map`][source-map] package's `SourceMapGenerator`. This
provides the same `addMapping` and `setSourceContent` API.
## Installation
```sh
npm install @jridgewell/gen-mapping
```
## Usage
```typescript
import { GenMapping, addMapping, setSourceContent, toEncodedMap, toDecodedMap } from '@jridgewell/gen-mapping';
const map = new GenMapping({
file: 'output.js',
sourceRoot: 'https://example.com/',
});
setSourceContent(map, 'input.js', `function foo() {}`);
addMapping(map, {
// Lines start at line 1, columns at column 0.
generated: { line: 1, column: 0 },
source: 'input.js',
original: { line: 1, column: 0 },
});
addMapping(map, {
generated: { line: 1, column: 9 },
source: 'input.js',
original: { line: 1, column: 9 },
name: 'foo',
});
assert.deepEqual(toDecodedMap(map), {
version: 3,
file: 'output.js',
names: ['foo'],
sourceRoot: 'https://example.com/',
sources: ['input.js'],
sourcesContent: ['function foo() {}'],
mappings: [
[ [0, 0, 0, 0], [9, 0, 0, 9, 0] ]
],
});
assert.deepEqual(toEncodedMap(map), {
version: 3,
file: 'output.js',
names: ['foo'],
sourceRoot: 'https://example.com/',
sources: ['input.js'],
sourcesContent: ['function foo() {}'],
mappings: 'AAAA,SAASA',
});
```
### Smaller Sourcemaps
Not everything needs to be added to a sourcemap, and needless markings can cause signficantly
larger file sizes. `gen-mapping` exposes `maybeAddSegment`/`maybeAddMapping` APIs that will
intelligently determine if this marking adds useful information. If not, the marking will be
skipped.
```typescript
import { maybeAddMapping } from '@jridgewell/gen-mapping';
const map = new GenMapping();
// Adding a sourceless marking at the beginning of a line isn't useful.
maybeAddMapping(map, {
generated: { line: 1, column: 0 },
});
// Adding a new source marking is useful.
maybeAddMapping(map, {
generated: { line: 1, column: 0 },
source: 'input.js',
original: { line: 1, column: 0 },
});
// But adding another marking pointing to the exact same original location isn't, even if the
// generated column changed.
maybeAddMapping(map, {
generated: { line: 1, column: 9 },
source: 'input.js',
original: { line: 1, column: 0 },
});
assert.deepEqual(toEncodedMap(map), {
version: 3,
names: [],
sources: ['input.js'],
sourcesContent: [null],
mappings: 'AAAA',
});
```
## Benchmarks
```
node v18.0.0
amp.js.map
Memory Usage:
gen-mapping: addSegment 5852872 bytes
gen-mapping: addMapping 7716042 bytes
source-map-js 6143250 bytes
source-map-0.6.1 6124102 bytes
source-map-0.8.0 6121173 bytes
Smallest memory usage is gen-mapping: addSegment
Adding speed:
gen-mapping: addSegment x 441 ops/sec ±2.07% (90 runs sampled)
gen-mapping: addMapping x 350 ops/sec ±2.40% (86 runs sampled)
source-map-js: addMapping x 169 ops/sec ±2.42% (80 runs sampled)
source-map-0.6.1: addMapping x 167 ops/sec ±2.56% (80 runs sampled)
source-map-0.8.0: addMapping x 168 ops/sec ±2.52% (80 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 150,824,370 ops/sec ±0.07% (102 runs sampled)
gen-mapping: encoded output x 663 ops/sec ±0.22% (98 runs sampled)
source-map-js: encoded output x 197 ops/sec ±0.45% (84 runs sampled)
source-map-0.6.1: encoded output x 198 ops/sec ±0.33% (85 runs sampled)
source-map-0.8.0: encoded output x 197 ops/sec ±0.06% (93 runs sampled)
Fastest is gen-mapping: decoded output
***
babel.min.js.map
Memory Usage:
gen-mapping: addSegment 37578063 bytes
gen-mapping: addMapping 37212897 bytes
source-map-js 47638527 bytes
source-map-0.6.1 47690503 bytes
source-map-0.8.0 47470188 bytes
Smallest memory usage is gen-mapping: addMapping
Adding speed:
gen-mapping: addSegment x 31.05 ops/sec ±8.31% (43 runs sampled)
gen-mapping: addMapping x 29.83 ops/sec ±7.36% (51 runs sampled)
source-map-js: addMapping x 20.73 ops/sec ±6.22% (38 runs sampled)
source-map-0.6.1: addMapping x 20.03 ops/sec ±10.51% (38 runs sampled)
source-map-0.8.0: addMapping x 19.30 ops/sec ±8.27% (37 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 381,379,234 ops/sec ±0.29% (96 runs sampled)
gen-mapping: encoded output x 95.15 ops/sec ±2.98% (72 runs sampled)
source-map-js: encoded output x 15.20 ops/sec ±7.41% (33 runs sampled)
source-map-0.6.1: encoded output x 16.36 ops/sec ±10.46% (31 runs sampled)
source-map-0.8.0: encoded output x 16.06 ops/sec ±6.45% (31 runs sampled)
Fastest is gen-mapping: decoded output
***
preact.js.map
Memory Usage:
gen-mapping: addSegment 416247 bytes
gen-mapping: addMapping 419824 bytes
source-map-js 1024619 bytes
source-map-0.6.1 1146004 bytes
source-map-0.8.0 1113250 bytes
Smallest memory usage is gen-mapping: addSegment
Adding speed:
gen-mapping: addSegment x 13,755 ops/sec ±0.15% (98 runs sampled)
gen-mapping: addMapping x 13,013 ops/sec ±0.11% (101 runs sampled)
source-map-js: addMapping x 4,564 ops/sec ±0.21% (98 runs sampled)
source-map-0.6.1: addMapping x 4,562 ops/sec ±0.11% (99 runs sampled)
source-map-0.8.0: addMapping x 4,593 ops/sec ±0.11% (100 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 379,864,020 ops/sec ±0.23% (93 runs sampled)
gen-mapping: encoded output x 14,368 ops/sec ±4.07% (82 runs sampled)
source-map-js: encoded output x 5,261 ops/sec ±0.21% (99 runs sampled)
source-map-0.6.1: encoded output x 5,124 ops/sec ±0.58% (99 runs sampled)
source-map-0.8.0: encoded output x 5,434 ops/sec ±0.33% (96 runs sampled)
Fastest is gen-mapping: decoded output
***
react.js.map
Memory Usage:
gen-mapping: addSegment 975096 bytes
gen-mapping: addMapping 1102981 bytes
source-map-js 2918836 bytes
source-map-0.6.1 2885435 bytes
source-map-0.8.0 2874336 bytes
Smallest memory usage is gen-mapping: addSegment
Adding speed:
gen-mapping: addSegment x 4,772 ops/sec ±0.15% (100 runs sampled)
gen-mapping: addMapping x 4,456 ops/sec ±0.13% (97 runs sampled)
source-map-js: addMapping x 1,618 ops/sec ±0.24% (97 runs sampled)
source-map-0.6.1: addMapping x 1,622 ops/sec ±0.12% (99 runs sampled)
source-map-0.8.0: addMapping x 1,631 ops/sec ±0.12% (100 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 379,107,695 ops/sec ±0.07% (99 runs sampled)
gen-mapping: encoded output x 5,421 ops/sec ±1.60% (89 runs sampled)
source-map-js: encoded output x 2,113 ops/sec ±1.81% (98 runs sampled)
source-map-0.6.1: encoded output x 2,126 ops/sec ±0.10% (100 runs sampled)
source-map-0.8.0: encoded output x 2,176 ops/sec ±0.39% (98 runs sampled)
Fastest is gen-mapping: decoded output
```
[source-map]: https://www.npmjs.com/package/source-map
[trace-mapping]: https://github.com/jridgewell/sourcemaps/tree/main/packages/trace-mapping
+292
View File
@@ -0,0 +1,292 @@
// src/set-array.ts
var SetArray = class {
constructor() {
this._indexes = { __proto__: null };
this.array = [];
}
};
function cast(set) {
return set;
}
function get(setarr, key) {
return cast(setarr)._indexes[key];
}
function put(setarr, key) {
const index = get(setarr, key);
if (index !== void 0) return index;
const { array, _indexes: indexes } = cast(setarr);
const length = array.push(key);
return indexes[key] = length - 1;
}
function remove(setarr, key) {
const index = get(setarr, key);
if (index === void 0) return;
const { array, _indexes: indexes } = cast(setarr);
for (let i = index + 1; i < array.length; i++) {
const k = array[i];
array[i - 1] = k;
indexes[k]--;
}
indexes[key] = void 0;
array.pop();
}
// src/gen-mapping.ts
import {
encode
} from "@jridgewell/sourcemap-codec";
import { TraceMap, decodedMappings } from "@jridgewell/trace-mapping";
// src/sourcemap-segment.ts
var COLUMN = 0;
var SOURCES_INDEX = 1;
var SOURCE_LINE = 2;
var SOURCE_COLUMN = 3;
var NAMES_INDEX = 4;
// src/gen-mapping.ts
var NO_NAME = -1;
var GenMapping = class {
constructor({ file, sourceRoot } = {}) {
this._names = new SetArray();
this._sources = new SetArray();
this._sourcesContent = [];
this._mappings = [];
this.file = file;
this.sourceRoot = sourceRoot;
this._ignoreList = new SetArray();
}
};
function cast2(map) {
return map;
}
function addSegment(map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
return addSegmentInternal(
false,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content
);
}
function addMapping(map, mapping) {
return addMappingInternal(false, map, mapping);
}
var maybeAddSegment = (map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) => {
return addSegmentInternal(
true,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content
);
};
var maybeAddMapping = (map, mapping) => {
return addMappingInternal(true, map, mapping);
};
function setSourceContent(map, source, content) {
const {
_sources: sources,
_sourcesContent: sourcesContent
// _originalScopes: originalScopes,
} = cast2(map);
const index = put(sources, source);
sourcesContent[index] = content;
}
function setIgnore(map, source, ignore = true) {
const {
_sources: sources,
_sourcesContent: sourcesContent,
_ignoreList: ignoreList
// _originalScopes: originalScopes,
} = cast2(map);
const index = put(sources, source);
if (index === sourcesContent.length) sourcesContent[index] = null;
if (ignore) put(ignoreList, index);
else remove(ignoreList, index);
}
function toDecodedMap(map) {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names,
_ignoreList: ignoreList
// _originalScopes: originalScopes,
// _generatedRanges: generatedRanges,
} = cast2(map);
removeEmptyFinalLines(mappings);
return {
version: 3,
file: map.file || void 0,
names: names.array,
sourceRoot: map.sourceRoot || void 0,
sources: sources.array,
sourcesContent,
mappings,
// originalScopes,
// generatedRanges,
ignoreList: ignoreList.array
};
}
function toEncodedMap(map) {
const decoded = toDecodedMap(map);
return Object.assign({}, decoded, {
// originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)),
// generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]),
mappings: encode(decoded.mappings)
});
}
function fromMap(input) {
const map = new TraceMap(input);
const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
putAll(cast2(gen)._names, map.names);
putAll(cast2(gen)._sources, map.sources);
cast2(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null);
cast2(gen)._mappings = decodedMappings(map);
if (map.ignoreList) putAll(cast2(gen)._ignoreList, map.ignoreList);
return gen;
}
function allMappings(map) {
const out = [];
const { _mappings: mappings, _sources: sources, _names: names } = cast2(map);
for (let i = 0; i < mappings.length; i++) {
const line = mappings[i];
for (let j = 0; j < line.length; j++) {
const seg = line[j];
const generated = { line: i + 1, column: seg[COLUMN] };
let source = void 0;
let original = void 0;
let name = void 0;
if (seg.length !== 1) {
source = sources.array[seg[SOURCES_INDEX]];
original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
}
out.push({ generated, source, original, name });
}
}
return out;
}
function addSegmentInternal(skipable, map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names
// _originalScopes: originalScopes,
} = cast2(map);
const line = getIndex(mappings, genLine);
const index = getColumnIndex(line, genColumn);
if (!source) {
if (skipable && skipSourceless(line, index)) return;
return insert(line, index, [genColumn]);
}
assert(sourceLine);
assert(sourceColumn);
const sourcesIndex = put(sources, source);
const namesIndex = name ? put(names, name) : NO_NAME;
if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content != null ? content : null;
if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) {
return;
}
return insert(
line,
index,
name ? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] : [genColumn, sourcesIndex, sourceLine, sourceColumn]
);
}
function assert(_val) {
}
function getIndex(arr, index) {
for (let i = arr.length; i <= index; i++) {
arr[i] = [];
}
return arr[index];
}
function getColumnIndex(line, genColumn) {
let index = line.length;
for (let i = index - 1; i >= 0; index = i--) {
const current = line[i];
if (genColumn >= current[COLUMN]) break;
}
return index;
}
function insert(array, index, value) {
for (let i = array.length; i > index; i--) {
array[i] = array[i - 1];
}
array[index] = value;
}
function removeEmptyFinalLines(mappings) {
const { length } = mappings;
let len = length;
for (let i = len - 1; i >= 0; len = i, i--) {
if (mappings[i].length > 0) break;
}
if (len < length) mappings.length = len;
}
function putAll(setarr, array) {
for (let i = 0; i < array.length; i++) put(setarr, array[i]);
}
function skipSourceless(line, index) {
if (index === 0) return true;
const prev = line[index - 1];
return prev.length === 1;
}
function skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex) {
if (index === 0) return false;
const prev = line[index - 1];
if (prev.length === 1) return false;
return sourcesIndex === prev[SOURCES_INDEX] && sourceLine === prev[SOURCE_LINE] && sourceColumn === prev[SOURCE_COLUMN] && namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME);
}
function addMappingInternal(skipable, map, mapping) {
const { generated, source, original, name, content } = mapping;
if (!source) {
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
null,
null,
null,
null,
null
);
}
assert(original);
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
source,
original.line - 1,
original.column,
name,
content
);
}
export {
GenMapping,
addMapping,
addSegment,
allMappings,
fromMap,
maybeAddMapping,
maybeAddSegment,
setIgnore,
setSourceContent,
toDecodedMap,
toEncodedMap
};
//# sourceMappingURL=gen-mapping.mjs.map
File diff suppressed because one or more lines are too long
+358
View File
@@ -0,0 +1,358 @@
(function (global, factory) {
if (typeof exports === 'object' && typeof module !== 'undefined') {
factory(module, require('@jridgewell/sourcemap-codec'), require('@jridgewell/trace-mapping'));
module.exports = def(module);
} else if (typeof define === 'function' && define.amd) {
define(['module', '@jridgewell/sourcemap-codec', '@jridgewell/trace-mapping'], function(mod) {
factory.apply(this, arguments);
mod.exports = def(mod);
});
} else {
const mod = { exports: {} };
factory(mod, global.sourcemapCodec, global.traceMapping);
global = typeof globalThis !== 'undefined' ? globalThis : global || self;
global.genMapping = def(mod);
}
function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; }
})(this, (function (module, require_sourcemapCodec, require_traceMapping) {
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// umd:@jridgewell/sourcemap-codec
var require_sourcemap_codec = __commonJS({
"umd:@jridgewell/sourcemap-codec"(exports, module2) {
module2.exports = require_sourcemapCodec;
}
});
// umd:@jridgewell/trace-mapping
var require_trace_mapping = __commonJS({
"umd:@jridgewell/trace-mapping"(exports, module2) {
module2.exports = require_traceMapping;
}
});
// src/gen-mapping.ts
var gen_mapping_exports = {};
__export(gen_mapping_exports, {
GenMapping: () => GenMapping,
addMapping: () => addMapping,
addSegment: () => addSegment,
allMappings: () => allMappings,
fromMap: () => fromMap,
maybeAddMapping: () => maybeAddMapping,
maybeAddSegment: () => maybeAddSegment,
setIgnore: () => setIgnore,
setSourceContent: () => setSourceContent,
toDecodedMap: () => toDecodedMap,
toEncodedMap: () => toEncodedMap
});
module.exports = __toCommonJS(gen_mapping_exports);
// src/set-array.ts
var SetArray = class {
constructor() {
this._indexes = { __proto__: null };
this.array = [];
}
};
function cast(set) {
return set;
}
function get(setarr, key) {
return cast(setarr)._indexes[key];
}
function put(setarr, key) {
const index = get(setarr, key);
if (index !== void 0) return index;
const { array, _indexes: indexes } = cast(setarr);
const length = array.push(key);
return indexes[key] = length - 1;
}
function remove(setarr, key) {
const index = get(setarr, key);
if (index === void 0) return;
const { array, _indexes: indexes } = cast(setarr);
for (let i = index + 1; i < array.length; i++) {
const k = array[i];
array[i - 1] = k;
indexes[k]--;
}
indexes[key] = void 0;
array.pop();
}
// src/gen-mapping.ts
var import_sourcemap_codec = __toESM(require_sourcemap_codec());
var import_trace_mapping = __toESM(require_trace_mapping());
// src/sourcemap-segment.ts
var COLUMN = 0;
var SOURCES_INDEX = 1;
var SOURCE_LINE = 2;
var SOURCE_COLUMN = 3;
var NAMES_INDEX = 4;
// src/gen-mapping.ts
var NO_NAME = -1;
var GenMapping = class {
constructor({ file, sourceRoot } = {}) {
this._names = new SetArray();
this._sources = new SetArray();
this._sourcesContent = [];
this._mappings = [];
this.file = file;
this.sourceRoot = sourceRoot;
this._ignoreList = new SetArray();
}
};
function cast2(map) {
return map;
}
function addSegment(map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
return addSegmentInternal(
false,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content
);
}
function addMapping(map, mapping) {
return addMappingInternal(false, map, mapping);
}
var maybeAddSegment = (map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) => {
return addSegmentInternal(
true,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content
);
};
var maybeAddMapping = (map, mapping) => {
return addMappingInternal(true, map, mapping);
};
function setSourceContent(map, source, content) {
const {
_sources: sources,
_sourcesContent: sourcesContent
// _originalScopes: originalScopes,
} = cast2(map);
const index = put(sources, source);
sourcesContent[index] = content;
}
function setIgnore(map, source, ignore = true) {
const {
_sources: sources,
_sourcesContent: sourcesContent,
_ignoreList: ignoreList
// _originalScopes: originalScopes,
} = cast2(map);
const index = put(sources, source);
if (index === sourcesContent.length) sourcesContent[index] = null;
if (ignore) put(ignoreList, index);
else remove(ignoreList, index);
}
function toDecodedMap(map) {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names,
_ignoreList: ignoreList
// _originalScopes: originalScopes,
// _generatedRanges: generatedRanges,
} = cast2(map);
removeEmptyFinalLines(mappings);
return {
version: 3,
file: map.file || void 0,
names: names.array,
sourceRoot: map.sourceRoot || void 0,
sources: sources.array,
sourcesContent,
mappings,
// originalScopes,
// generatedRanges,
ignoreList: ignoreList.array
};
}
function toEncodedMap(map) {
const decoded = toDecodedMap(map);
return Object.assign({}, decoded, {
// originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)),
// generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]),
mappings: (0, import_sourcemap_codec.encode)(decoded.mappings)
});
}
function fromMap(input) {
const map = new import_trace_mapping.TraceMap(input);
const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
putAll(cast2(gen)._names, map.names);
putAll(cast2(gen)._sources, map.sources);
cast2(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null);
cast2(gen)._mappings = (0, import_trace_mapping.decodedMappings)(map);
if (map.ignoreList) putAll(cast2(gen)._ignoreList, map.ignoreList);
return gen;
}
function allMappings(map) {
const out = [];
const { _mappings: mappings, _sources: sources, _names: names } = cast2(map);
for (let i = 0; i < mappings.length; i++) {
const line = mappings[i];
for (let j = 0; j < line.length; j++) {
const seg = line[j];
const generated = { line: i + 1, column: seg[COLUMN] };
let source = void 0;
let original = void 0;
let name = void 0;
if (seg.length !== 1) {
source = sources.array[seg[SOURCES_INDEX]];
original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
}
out.push({ generated, source, original, name });
}
}
return out;
}
function addSegmentInternal(skipable, map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names
// _originalScopes: originalScopes,
} = cast2(map);
const line = getIndex(mappings, genLine);
const index = getColumnIndex(line, genColumn);
if (!source) {
if (skipable && skipSourceless(line, index)) return;
return insert(line, index, [genColumn]);
}
assert(sourceLine);
assert(sourceColumn);
const sourcesIndex = put(sources, source);
const namesIndex = name ? put(names, name) : NO_NAME;
if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content != null ? content : null;
if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) {
return;
}
return insert(
line,
index,
name ? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] : [genColumn, sourcesIndex, sourceLine, sourceColumn]
);
}
function assert(_val) {
}
function getIndex(arr, index) {
for (let i = arr.length; i <= index; i++) {
arr[i] = [];
}
return arr[index];
}
function getColumnIndex(line, genColumn) {
let index = line.length;
for (let i = index - 1; i >= 0; index = i--) {
const current = line[i];
if (genColumn >= current[COLUMN]) break;
}
return index;
}
function insert(array, index, value) {
for (let i = array.length; i > index; i--) {
array[i] = array[i - 1];
}
array[index] = value;
}
function removeEmptyFinalLines(mappings) {
const { length } = mappings;
let len = length;
for (let i = len - 1; i >= 0; len = i, i--) {
if (mappings[i].length > 0) break;
}
if (len < length) mappings.length = len;
}
function putAll(setarr, array) {
for (let i = 0; i < array.length; i++) put(setarr, array[i]);
}
function skipSourceless(line, index) {
if (index === 0) return true;
const prev = line[index - 1];
return prev.length === 1;
}
function skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex) {
if (index === 0) return false;
const prev = line[index - 1];
if (prev.length === 1) return false;
return sourcesIndex === prev[SOURCES_INDEX] && sourceLine === prev[SOURCE_LINE] && sourceColumn === prev[SOURCE_COLUMN] && namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME);
}
function addMappingInternal(skipable, map, mapping) {
const { generated, source, original, name, content } = mapping;
if (!source) {
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
null,
null,
null,
null,
null
);
}
assert(original);
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
source,
original.line - 1,
original.column,
name,
content
);
}
}));
//# sourceMappingURL=gen-mapping.umd.js.map
File diff suppressed because one or more lines are too long
+88
View File
@@ -0,0 +1,88 @@
import type { SourceMapInput } from '@jridgewell/trace-mapping';
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types';
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
export type Options = {
file?: string | null;
sourceRoot?: string | null;
};
/**
* Provides the state to generate a sourcemap.
*/
export declare class GenMapping {
private _names;
private _sources;
private _sourcesContent;
private _mappings;
private _ignoreList;
file: string | null | undefined;
sourceRoot: string | null | undefined;
constructor({ file, sourceRoot }?: Options);
}
/**
* A low-level API to associate a generated position with an original source position. Line and
* column here are 0-based, unlike `addMapping`.
*/
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
/**
* A high-level API to associate a generated position with an original source position. Line is
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
*/
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source?: null;
original?: null;
name?: null;
content?: null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name?: null;
content?: string | null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name: string;
content?: string | null;
}): void;
/**
* Same as `addSegment`, but will only add the segment if it generates useful information in the
* resulting map. This only works correctly if segments are added **in order**, meaning you should
* not add a segment with a lower generated line/column than one that came before.
*/
export declare const maybeAddSegment: typeof addSegment;
/**
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
* not add a mapping with a lower generated line/column than one that came before.
*/
export declare const maybeAddMapping: typeof addMapping;
/**
* Adds/removes the content of the source file to the source map.
*/
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
/**
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
/**
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
/**
* Constructs a new GenMapping, using the already present mappings of the input.
*/
export declare function fromMap(input: SourceMapInput): GenMapping;
/**
* Returns an array of high-level mapping objects for every recorded segment, which could then be
* passed to the `source-map` library.
*/
export declare function allMappings(map: GenMapping): Mapping[];
+32
View File
@@ -0,0 +1,32 @@
type Key = string | number | symbol;
/**
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
* index of the `key` in the backing array.
*
* This is designed to allow synchronizing a second array with the contents of the backing array,
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
* and there are never duplicates.
*/
export declare class SetArray<T extends Key = Key> {
private _indexes;
array: readonly T[];
constructor();
}
/**
* Gets the index associated with `key` in the backing array, if it is already present.
*/
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
/**
* Puts `key` into the backing array, if it is not already present. Returns
* the index of the `key` in the backing array.
*/
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
/**
* Pops the last added item out of the SetArray.
*/
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
/**
* Removes the key, if it exists in the set.
*/
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
export {};
+12
View File
@@ -0,0 +1,12 @@
type GeneratedColumn = number;
type SourcesIndex = number;
type SourceLine = number;
type SourceColumn = number;
type NamesIndex = number;
export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
export declare const COLUMN = 0;
export declare const SOURCES_INDEX = 1;
export declare const SOURCE_LINE = 2;
export declare const SOURCE_COLUMN = 3;
export declare const NAMES_INDEX = 4;
export {};
+43
View File
@@ -0,0 +1,43 @@
import type { SourceMapSegment } from './sourcemap-segment';
export interface SourceMapV3 {
file?: string | null;
names: readonly string[];
sourceRoot?: string;
sources: readonly (string | null)[];
sourcesContent?: readonly (string | null)[];
version: 3;
ignoreList?: readonly number[];
}
export interface EncodedSourceMap extends SourceMapV3 {
mappings: string;
}
export interface DecodedSourceMap extends SourceMapV3 {
mappings: readonly SourceMapSegment[][];
}
export interface Pos {
line: number;
column: number;
}
export interface OriginalPos extends Pos {
source: string;
}
export interface BindingExpressionRange {
start: Pos;
expression: string;
}
export type Mapping = {
generated: Pos;
source: undefined;
original: undefined;
name: undefined;
} | {
generated: Pos;
source: string;
original: Pos;
name: string;
} | {
generated: Pos;
source: string;
original: Pos;
name: undefined;
};
+67
View File
@@ -0,0 +1,67 @@
{
"name": "@jridgewell/gen-mapping",
"version": "0.3.13",
"description": "Generate source maps",
"keywords": [
"source",
"map"
],
"main": "dist/gen-mapping.umd.js",
"module": "dist/gen-mapping.mjs",
"types": "types/gen-mapping.d.cts",
"files": [
"dist",
"src",
"types"
],
"exports": {
".": [
{
"import": {
"types": "./types/gen-mapping.d.mts",
"default": "./dist/gen-mapping.mjs"
},
"default": {
"types": "./types/gen-mapping.d.cts",
"default": "./dist/gen-mapping.umd.js"
}
},
"./dist/gen-mapping.umd.js"
],
"./package.json": "./package.json"
},
"scripts": {
"benchmark": "run-s build:code benchmark:*",
"benchmark:install": "cd benchmark && npm install",
"benchmark:only": "node --expose-gc benchmark/index.js",
"build": "run-s -n build:code build:types",
"build:code": "node ../../esbuild.mjs gen-mapping.ts",
"build:types": "run-s build:types:force build:types:emit build:types:mts",
"build:types:force": "rimraf tsconfig.build.tsbuildinfo",
"build:types:emit": "tsc --project tsconfig.build.json",
"build:types:mts": "node ../../mts-types.mjs",
"clean": "run-s -n clean:code clean:types",
"clean:code": "tsc --build --clean tsconfig.build.json",
"clean:types": "rimraf dist types",
"test": "run-s -n test:types test:only test:format",
"test:format": "prettier --check '{src,test}/**/*.ts'",
"test:only": "mocha",
"test:types": "eslint '{src,test}/**/*.ts'",
"lint": "run-s -n lint:types lint:format",
"lint:format": "npm run test:format -- --write",
"lint:types": "npm run test:types -- --fix",
"prepublishOnly": "npm run-s -n build test"
},
"homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/gen-mapping",
"repository": {
"type": "git",
"url": "git+https://github.com/jridgewell/sourcemaps.git",
"directory": "packages/gen-mapping"
},
"author": "Justin Ridgewell <justin@ridgewell.name>",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
}
+614
View File
@@ -0,0 +1,614 @@
import { SetArray, put, remove } from './set-array';
import {
encode,
// encodeGeneratedRanges,
// encodeOriginalScopes
} from '@jridgewell/sourcemap-codec';
import { TraceMap, decodedMappings } from '@jridgewell/trace-mapping';
import {
COLUMN,
SOURCES_INDEX,
SOURCE_LINE,
SOURCE_COLUMN,
NAMES_INDEX,
} from './sourcemap-segment';
import type { SourceMapInput } from '@jridgewell/trace-mapping';
// import type { OriginalScope, GeneratedRange } from '@jridgewell/sourcemap-codec';
import type { SourceMapSegment } from './sourcemap-segment';
import type {
DecodedSourceMap,
EncodedSourceMap,
Pos,
Mapping,
// BindingExpressionRange,
// OriginalPos,
// OriginalScopeInfo,
// GeneratedRangeInfo,
} from './types';
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
export type Options = {
file?: string | null;
sourceRoot?: string | null;
};
const NO_NAME = -1;
/**
* Provides the state to generate a sourcemap.
*/
export class GenMapping {
declare private _names: SetArray<string>;
declare private _sources: SetArray<string>;
declare private _sourcesContent: (string | null)[];
declare private _mappings: SourceMapSegment[][];
// private declare _originalScopes: OriginalScope[][];
// private declare _generatedRanges: GeneratedRange[];
declare private _ignoreList: SetArray<number>;
declare file: string | null | undefined;
declare sourceRoot: string | null | undefined;
constructor({ file, sourceRoot }: Options = {}) {
this._names = new SetArray();
this._sources = new SetArray();
this._sourcesContent = [];
this._mappings = [];
// this._originalScopes = [];
// this._generatedRanges = [];
this.file = file;
this.sourceRoot = sourceRoot;
this._ignoreList = new SetArray();
}
}
interface PublicMap {
_names: GenMapping['_names'];
_sources: GenMapping['_sources'];
_sourcesContent: GenMapping['_sourcesContent'];
_mappings: GenMapping['_mappings'];
// _originalScopes: GenMapping['_originalScopes'];
// _generatedRanges: GenMapping['_generatedRanges'];
_ignoreList: GenMapping['_ignoreList'];
}
/**
* Typescript doesn't allow friend access to private fields, so this just casts the map into a type
* with public access modifiers.
*/
function cast(map: unknown): PublicMap {
return map as any;
}
/**
* A low-level API to associate a generated position with an original source position. Line and
* column here are 0-based, unlike `addMapping`.
*/
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source?: null,
sourceLine?: null,
sourceColumn?: null,
name?: null,
content?: null,
): void;
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source: string,
sourceLine: number,
sourceColumn: number,
name?: null,
content?: string | null,
): void;
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source: string,
sourceLine: number,
sourceColumn: number,
name: string,
content?: string | null,
): void;
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source?: string | null,
sourceLine?: number | null,
sourceColumn?: number | null,
name?: string | null,
content?: string | null,
): void {
return addSegmentInternal(
false,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content,
);
}
/**
* A high-level API to associate a generated position with an original source position. Line is
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
*/
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source?: null;
original?: null;
name?: null;
content?: null;
},
): void;
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source: string;
original: Pos;
name?: null;
content?: string | null;
},
): void;
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source: string;
original: Pos;
name: string;
content?: string | null;
},
): void;
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source?: string | null;
original?: Pos | null;
name?: string | null;
content?: string | null;
},
): void {
return addMappingInternal(false, map, mapping as Parameters<typeof addMappingInternal>[2]);
}
/**
* Same as `addSegment`, but will only add the segment if it generates useful information in the
* resulting map. This only works correctly if segments are added **in order**, meaning you should
* not add a segment with a lower generated line/column than one that came before.
*/
export const maybeAddSegment: typeof addSegment = (
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content,
) => {
return addSegmentInternal(
true,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content,
);
};
/**
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
* not add a mapping with a lower generated line/column than one that came before.
*/
export const maybeAddMapping: typeof addMapping = (map, mapping) => {
return addMappingInternal(true, map, mapping as Parameters<typeof addMappingInternal>[2]);
};
/**
* Adds/removes the content of the source file to the source map.
*/
export function setSourceContent(map: GenMapping, source: string, content: string | null): void {
const {
_sources: sources,
_sourcesContent: sourcesContent,
// _originalScopes: originalScopes,
} = cast(map);
const index = put(sources, source);
sourcesContent[index] = content;
// if (index === originalScopes.length) originalScopes[index] = [];
}
export function setIgnore(map: GenMapping, source: string, ignore = true) {
const {
_sources: sources,
_sourcesContent: sourcesContent,
_ignoreList: ignoreList,
// _originalScopes: originalScopes,
} = cast(map);
const index = put(sources, source);
if (index === sourcesContent.length) sourcesContent[index] = null;
// if (index === originalScopes.length) originalScopes[index] = [];
if (ignore) put(ignoreList, index);
else remove(ignoreList, index);
}
/**
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export function toDecodedMap(map: GenMapping): DecodedSourceMap {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names,
_ignoreList: ignoreList,
// _originalScopes: originalScopes,
// _generatedRanges: generatedRanges,
} = cast(map);
removeEmptyFinalLines(mappings);
return {
version: 3,
file: map.file || undefined,
names: names.array,
sourceRoot: map.sourceRoot || undefined,
sources: sources.array,
sourcesContent,
mappings,
// originalScopes,
// generatedRanges,
ignoreList: ignoreList.array,
};
}
/**
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export function toEncodedMap(map: GenMapping): EncodedSourceMap {
const decoded = toDecodedMap(map);
return Object.assign({}, decoded, {
// originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)),
// generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]),
mappings: encode(decoded.mappings as SourceMapSegment[][]),
});
}
/**
* Constructs a new GenMapping, using the already present mappings of the input.
*/
export function fromMap(input: SourceMapInput): GenMapping {
const map = new TraceMap(input);
const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
putAll(cast(gen)._names, map.names);
putAll(cast(gen)._sources, map.sources as string[]);
cast(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null);
cast(gen)._mappings = decodedMappings(map) as GenMapping['_mappings'];
// TODO: implement originalScopes/generatedRanges
if (map.ignoreList) putAll(cast(gen)._ignoreList, map.ignoreList);
return gen;
}
/**
* Returns an array of high-level mapping objects for every recorded segment, which could then be
* passed to the `source-map` library.
*/
export function allMappings(map: GenMapping): Mapping[] {
const out: Mapping[] = [];
const { _mappings: mappings, _sources: sources, _names: names } = cast(map);
for (let i = 0; i < mappings.length; i++) {
const line = mappings[i];
for (let j = 0; j < line.length; j++) {
const seg = line[j];
const generated = { line: i + 1, column: seg[COLUMN] };
let source: string | undefined = undefined;
let original: Pos | undefined = undefined;
let name: string | undefined = undefined;
if (seg.length !== 1) {
source = sources.array[seg[SOURCES_INDEX]];
original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
}
out.push({ generated, source, original, name } as Mapping);
}
}
return out;
}
// This split declaration is only so that terser can elminiate the static initialization block.
function addSegmentInternal<S extends string | null | undefined>(
skipable: boolean,
map: GenMapping,
genLine: number,
genColumn: number,
source: S,
sourceLine: S extends string ? number : null | undefined,
sourceColumn: S extends string ? number : null | undefined,
name: S extends string ? string | null | undefined : null | undefined,
content: S extends string ? string | null | undefined : null | undefined,
): void {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names,
// _originalScopes: originalScopes,
} = cast(map);
const line = getIndex(mappings, genLine);
const index = getColumnIndex(line, genColumn);
if (!source) {
if (skipable && skipSourceless(line, index)) return;
return insert(line, index, [genColumn]);
}
// Sigh, TypeScript can't figure out sourceLine and sourceColumn aren't nullish if source
// isn't nullish.
assert<number>(sourceLine);
assert<number>(sourceColumn);
const sourcesIndex = put(sources, source);
const namesIndex = name ? put(names, name) : NO_NAME;
if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content ?? null;
// if (sourcesIndex === originalScopes.length) originalScopes[sourcesIndex] = [];
if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) {
return;
}
return insert(
line,
index,
name
? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]
: [genColumn, sourcesIndex, sourceLine, sourceColumn],
);
}
function assert<T>(_val: unknown): asserts _val is T {
// noop.
}
function getIndex<T>(arr: T[][], index: number): T[] {
for (let i = arr.length; i <= index; i++) {
arr[i] = [];
}
return arr[index];
}
function getColumnIndex(line: SourceMapSegment[], genColumn: number): number {
let index = line.length;
for (let i = index - 1; i >= 0; index = i--) {
const current = line[i];
if (genColumn >= current[COLUMN]) break;
}
return index;
}
function insert<T>(array: T[], index: number, value: T) {
for (let i = array.length; i > index; i--) {
array[i] = array[i - 1];
}
array[index] = value;
}
function removeEmptyFinalLines(mappings: SourceMapSegment[][]) {
const { length } = mappings;
let len = length;
for (let i = len - 1; i >= 0; len = i, i--) {
if (mappings[i].length > 0) break;
}
if (len < length) mappings.length = len;
}
function putAll<T extends string | number>(setarr: SetArray<T>, array: T[]) {
for (let i = 0; i < array.length; i++) put(setarr, array[i]);
}
function skipSourceless(line: SourceMapSegment[], index: number): boolean {
// The start of a line is already sourceless, so adding a sourceless segment to the beginning
// doesn't generate any useful information.
if (index === 0) return true;
const prev = line[index - 1];
// If the previous segment is also sourceless, then adding another sourceless segment doesn't
// genrate any new information. Else, this segment will end the source/named segment and point to
// a sourceless position, which is useful.
return prev.length === 1;
}
function skipSource(
line: SourceMapSegment[],
index: number,
sourcesIndex: number,
sourceLine: number,
sourceColumn: number,
namesIndex: number,
): boolean {
// A source/named segment at the start of a line gives position at that genColumn
if (index === 0) return false;
const prev = line[index - 1];
// If the previous segment is sourceless, then we're transitioning to a source.
if (prev.length === 1) return false;
// If the previous segment maps to the exact same source position, then this segment doesn't
// provide any new position information.
return (
sourcesIndex === prev[SOURCES_INDEX] &&
sourceLine === prev[SOURCE_LINE] &&
sourceColumn === prev[SOURCE_COLUMN] &&
namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME)
);
}
function addMappingInternal<S extends string | null | undefined>(
skipable: boolean,
map: GenMapping,
mapping: {
generated: Pos;
source: S;
original: S extends string ? Pos : null | undefined;
name: S extends string ? string | null | undefined : null | undefined;
content: S extends string ? string | null | undefined : null | undefined;
},
) {
const { generated, source, original, name, content } = mapping;
if (!source) {
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
null,
null,
null,
null,
null,
);
}
assert<Pos>(original);
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
source as string,
original.line - 1,
original.column,
name,
content,
);
}
/*
export function addOriginalScope(
map: GenMapping,
data: {
start: Pos;
end: Pos;
source: string;
kind: string;
name?: string;
variables?: string[];
},
): OriginalScopeInfo {
const { start, end, source, kind, name, variables } = data;
const {
_sources: sources,
_sourcesContent: sourcesContent,
_originalScopes: originalScopes,
_names: names,
} = cast(map);
const index = put(sources, source);
if (index === sourcesContent.length) sourcesContent[index] = null;
if (index === originalScopes.length) originalScopes[index] = [];
const kindIndex = put(names, kind);
const scope: OriginalScope = name
? [start.line - 1, start.column, end.line - 1, end.column, kindIndex, put(names, name)]
: [start.line - 1, start.column, end.line - 1, end.column, kindIndex];
if (variables) {
scope.vars = variables.map((v) => put(names, v));
}
const len = originalScopes[index].push(scope);
return [index, len - 1, variables];
}
*/
// Generated Ranges
/*
export function addGeneratedRange(
map: GenMapping,
data: {
start: Pos;
isScope: boolean;
originalScope?: OriginalScopeInfo;
callsite?: OriginalPos;
},
): GeneratedRangeInfo {
const { start, isScope, originalScope, callsite } = data;
const {
_originalScopes: originalScopes,
_sources: sources,
_sourcesContent: sourcesContent,
_generatedRanges: generatedRanges,
} = cast(map);
const range: GeneratedRange = [
start.line - 1,
start.column,
0,
0,
originalScope ? originalScope[0] : -1,
originalScope ? originalScope[1] : -1,
];
if (originalScope?.[2]) {
range.bindings = originalScope[2].map(() => [[-1]]);
}
if (callsite) {
const index = put(sources, callsite.source);
if (index === sourcesContent.length) sourcesContent[index] = null;
if (index === originalScopes.length) originalScopes[index] = [];
range.callsite = [index, callsite.line - 1, callsite.column];
}
if (isScope) range.isScope = true;
generatedRanges.push(range);
return [range, originalScope?.[2]];
}
export function setEndPosition(range: GeneratedRangeInfo, pos: Pos) {
range[0][2] = pos.line - 1;
range[0][3] = pos.column;
}
export function addBinding(
map: GenMapping,
range: GeneratedRangeInfo,
variable: string,
expression: string | BindingExpressionRange,
) {
const { _names: names } = cast(map);
const bindings = (range[0].bindings ||= []);
const vars = range[1];
const index = vars!.indexOf(variable);
const binding = getIndex(bindings, index);
if (typeof expression === 'string') binding[0] = [put(names, expression)];
else {
const { start } = expression;
binding.push([put(names, expression.expression), start.line - 1, start.column]);
}
}
*/
+82
View File
@@ -0,0 +1,82 @@
type Key = string | number | symbol;
/**
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
* index of the `key` in the backing array.
*
* This is designed to allow synchronizing a second array with the contents of the backing array,
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
* and there are never duplicates.
*/
export class SetArray<T extends Key = Key> {
declare private _indexes: Record<T, number | undefined>;
declare array: readonly T[];
constructor() {
this._indexes = { __proto__: null } as any;
this.array = [];
}
}
interface PublicSet<T extends Key> {
array: T[];
_indexes: SetArray<T>['_indexes'];
}
/**
* Typescript doesn't allow friend access to private fields, so this just casts the set into a type
* with public access modifiers.
*/
function cast<T extends Key>(set: SetArray<T>): PublicSet<T> {
return set as any;
}
/**
* Gets the index associated with `key` in the backing array, if it is already present.
*/
export function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined {
return cast(setarr)._indexes[key];
}
/**
* Puts `key` into the backing array, if it is not already present. Returns
* the index of the `key` in the backing array.
*/
export function put<T extends Key>(setarr: SetArray<T>, key: T): number {
// The key may or may not be present. If it is present, it's a number.
const index = get(setarr, key);
if (index !== undefined) return index;
const { array, _indexes: indexes } = cast(setarr);
const length = array.push(key);
return (indexes[key] = length - 1);
}
/**
* Pops the last added item out of the SetArray.
*/
export function pop<T extends Key>(setarr: SetArray<T>): void {
const { array, _indexes: indexes } = cast(setarr);
if (array.length === 0) return;
const last = array.pop()!;
indexes[last] = undefined;
}
/**
* Removes the key, if it exists in the set.
*/
export function remove<T extends Key>(setarr: SetArray<T>, key: T): void {
const index = get(setarr, key);
if (index === undefined) return;
const { array, _indexes: indexes } = cast(setarr);
for (let i = index + 1; i < array.length; i++) {
const k = array[i];
array[i - 1] = k;
indexes[k]!--;
}
indexes[key] = undefined;
array.pop();
}
+16
View File
@@ -0,0 +1,16 @@
type GeneratedColumn = number;
type SourcesIndex = number;
type SourceLine = number;
type SourceColumn = number;
type NamesIndex = number;
export type SourceMapSegment =
| [GeneratedColumn]
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn]
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
export const COLUMN = 0;
export const SOURCES_INDEX = 1;
export const SOURCE_LINE = 2;
export const SOURCE_COLUMN = 3;
export const NAMES_INDEX = 4;
+61
View File
@@ -0,0 +1,61 @@
// import type { GeneratedRange, OriginalScope } from '@jridgewell/sourcemap-codec';
import type { SourceMapSegment } from './sourcemap-segment';
export interface SourceMapV3 {
file?: string | null;
names: readonly string[];
sourceRoot?: string;
sources: readonly (string | null)[];
sourcesContent?: readonly (string | null)[];
version: 3;
ignoreList?: readonly number[];
}
export interface EncodedSourceMap extends SourceMapV3 {
mappings: string;
// originalScopes: string[];
// generatedRanges: string;
}
export interface DecodedSourceMap extends SourceMapV3 {
mappings: readonly SourceMapSegment[][];
// originalScopes: readonly OriginalScope[][];
// generatedRanges: readonly GeneratedRange[];
}
export interface Pos {
line: number; // 1-based
column: number; // 0-based
}
export interface OriginalPos extends Pos {
source: string;
}
export interface BindingExpressionRange {
start: Pos;
expression: string;
}
// export type OriginalScopeInfo = [number, number, string[] | undefined];
// export type GeneratedRangeInfo = [GeneratedRange, string[] | undefined];
export type Mapping =
| {
generated: Pos;
source: undefined;
original: undefined;
name: undefined;
}
| {
generated: Pos;
source: string;
original: Pos;
name: string;
}
| {
generated: Pos;
source: string;
original: Pos;
name: undefined;
};
+89
View File
@@ -0,0 +1,89 @@
import type { SourceMapInput } from '@jridgewell/trace-mapping';
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.cts';
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
export type Options = {
file?: string | null;
sourceRoot?: string | null;
};
/**
* Provides the state to generate a sourcemap.
*/
export declare class GenMapping {
private _names;
private _sources;
private _sourcesContent;
private _mappings;
private _ignoreList;
file: string | null | undefined;
sourceRoot: string | null | undefined;
constructor({ file, sourceRoot }?: Options);
}
/**
* A low-level API to associate a generated position with an original source position. Line and
* column here are 0-based, unlike `addMapping`.
*/
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
/**
* A high-level API to associate a generated position with an original source position. Line is
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
*/
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source?: null;
original?: null;
name?: null;
content?: null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name?: null;
content?: string | null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name: string;
content?: string | null;
}): void;
/**
* Same as `addSegment`, but will only add the segment if it generates useful information in the
* resulting map. This only works correctly if segments are added **in order**, meaning you should
* not add a segment with a lower generated line/column than one that came before.
*/
export declare const maybeAddSegment: typeof addSegment;
/**
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
* not add a mapping with a lower generated line/column than one that came before.
*/
export declare const maybeAddMapping: typeof addMapping;
/**
* Adds/removes the content of the source file to the source map.
*/
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
/**
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
/**
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
/**
* Constructs a new GenMapping, using the already present mappings of the input.
*/
export declare function fromMap(input: SourceMapInput): GenMapping;
/**
* Returns an array of high-level mapping objects for every recorded segment, which could then be
* passed to the `source-map` library.
*/
export declare function allMappings(map: GenMapping): Mapping[];
//# sourceMappingURL=gen-mapping.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"}
+89
View File
@@ -0,0 +1,89 @@
import type { SourceMapInput } from '@jridgewell/trace-mapping';
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.mts';
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
export type Options = {
file?: string | null;
sourceRoot?: string | null;
};
/**
* Provides the state to generate a sourcemap.
*/
export declare class GenMapping {
private _names;
private _sources;
private _sourcesContent;
private _mappings;
private _ignoreList;
file: string | null | undefined;
sourceRoot: string | null | undefined;
constructor({ file, sourceRoot }?: Options);
}
/**
* A low-level API to associate a generated position with an original source position. Line and
* column here are 0-based, unlike `addMapping`.
*/
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
/**
* A high-level API to associate a generated position with an original source position. Line is
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
*/
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source?: null;
original?: null;
name?: null;
content?: null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name?: null;
content?: string | null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name: string;
content?: string | null;
}): void;
/**
* Same as `addSegment`, but will only add the segment if it generates useful information in the
* resulting map. This only works correctly if segments are added **in order**, meaning you should
* not add a segment with a lower generated line/column than one that came before.
*/
export declare const maybeAddSegment: typeof addSegment;
/**
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
* not add a mapping with a lower generated line/column than one that came before.
*/
export declare const maybeAddMapping: typeof addMapping;
/**
* Adds/removes the content of the source file to the source map.
*/
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
/**
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
/**
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
/**
* Constructs a new GenMapping, using the already present mappings of the input.
*/
export declare function fromMap(input: SourceMapInput): GenMapping;
/**
* Returns an array of high-level mapping objects for every recorded segment, which could then be
* passed to the `source-map` library.
*/
export declare function allMappings(map: GenMapping): Mapping[];
//# sourceMappingURL=gen-mapping.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"}
+33
View File
@@ -0,0 +1,33 @@
type Key = string | number | symbol;
/**
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
* index of the `key` in the backing array.
*
* This is designed to allow synchronizing a second array with the contents of the backing array,
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
* and there are never duplicates.
*/
export declare class SetArray<T extends Key = Key> {
private _indexes;
array: readonly T[];
constructor();
}
/**
* Gets the index associated with `key` in the backing array, if it is already present.
*/
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
/**
* Puts `key` into the backing array, if it is not already present. Returns
* the index of the `key` in the backing array.
*/
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
/**
* Pops the last added item out of the SetArray.
*/
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
/**
* Removes the key, if it exists in the set.
*/
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
export {};
//# sourceMappingURL=set-array.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"}
+33
View File
@@ -0,0 +1,33 @@
type Key = string | number | symbol;
/**
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
* index of the `key` in the backing array.
*
* This is designed to allow synchronizing a second array with the contents of the backing array,
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
* and there are never duplicates.
*/
export declare class SetArray<T extends Key = Key> {
private _indexes;
array: readonly T[];
constructor();
}
/**
* Gets the index associated with `key` in the backing array, if it is already present.
*/
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
/**
* Puts `key` into the backing array, if it is not already present. Returns
* the index of the `key` in the backing array.
*/
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
/**
* Pops the last added item out of the SetArray.
*/
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
/**
* Removes the key, if it exists in the set.
*/
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
export {};
//# sourceMappingURL=set-array.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"}

Some files were not shown because too many files have changed in this diff Show More