์ทจ์ ๊ฐ๋ฅํ,
์ฐ์ ์์๊ฐ ์๋,
๊ฐ์ ๋ฐ๊ฟ ์ ์๋ ์ด๋ฒคํธ
์บ์ฌ๋ฌ๋ธ์ Event ์ ํ&์ฒ๋ฆฌ ๋ชจ๋๋ก, Node.JS ์ EventEmitter ์ Minecraft ์ Bukkit Plugin ์ด๋ฒคํธ ์ฒด๊ณ์ ์๊ฐ์ ๋ฐ์ ๊ฐ๋ฐ๋ Node.JS ๋ชจ๋์
๋๋ค. MIT ๋ผ์ด์ผ์ค๋ก ์์ ๋กญ๊ฒ ์ด์ฉํ ์ ์์ผ๋ฉฐ, Webpack์ ํตํด ๋ธ๋ผ์ฐ์ ์์ ํธํ๋ ์ ์์ต๋๋ค.
npm install cancelable-event --save
์ด๋ฒคํธ ์์ ์๋ ์ด๋ฒคํธ์ ์ทจ์์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ ์ ์์ผ๋ฉฐ, ์ด๋ฒคํธ ์์ ์๋ ํด๋น ์ด๋ฒคํธ์ ์ทจ์์ฌ๋ถ์ ๋ฐ๋ผ ํน์ ์ฝ๋๋ฅผ ์คํํ๊ฑฐ๋ ์คํํ์ง ์์ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด์ ํน์ ์ด๋ฒคํธ์ ์คํ์ด ์ ํฉํ์ง๋ฅผ ์ ๋์ ์ผ๋ก ํ๊ฐํ ์คํํ ์ ์๊ฒ๋ฉ๋๋ค.
์ด๋ฒคํธ๋ ์ฐ์ ์์์ ๋ฐ๋ผ ์์ ์์๊ฒ ์ ๋ฌ๋๋ฉฐ, ์์ ์๋ ์ฐ์ ์์์ ๋ฐ๋ผ ์ด๋ฒคํธ ๊ฐ์ ๋จผ์ ๋ฐ์์ ์ต์ข ์ ์ผ๋ก ์ก์ ์์๊ฒ ์ ๋ฌ๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด์ ๋ชจ๋ ์ํฉ์ด ๊ณ ๋ ค๋ ์ด๋ฒคํธ์ ๊ฒฐ๊ณผ ๊ฐ์ ๋น์ฅ ๋ชจ๋ ์ด๋ฒคํธ ์ํฉ์ ๊ณ ๋ คํ์ง ์๊ณ ๋ ๋ง๋ค ์ ์๊ฒ๋ฉ๋๋ค.
์ด๋ฒคํธ๋ ์ด๋ฒคํธ ๊ฐ์ ์์ ๊ณผ์ ๊ณผ ์ด๋ฒคํธ ์ค๋จ์ ๊ฒฐ์ ํ ์์ ์ ์ ๋ณด๊ฐ ๋ชจ๋ ๊ธฐ๋ก๋์ด ์ด๋ฒคํธ ์ก์ ์์๊ฒ ์ ๋ฌ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด์ ๊ฐ์ ์์๊ณผ ๋ฌ๋ฆฌ ์์ ํ ์์ ์์ ์ญ์ถ์ ๋ฐ ์ด๋ฒคํธ๋ฅผ ์์๊ณผ ๋ค๋ฅด๊ฒ ์ค๋จํ ์์ ์ ์ญ์ถ์ ์ ์ด๋ฒคํธ ์ก์ ์ ํจ์์์ ํ ์ ์์ต๋๋ค. ์ฆ ์ ๋์ ์ธ ์ํฉ์ ๊ณ ๋ คํ ์ด๋ฒคํธ์ ๋๋ฒ๊น ์ด ๋งค์ฐ ํธ๋ฆฌํด์ง๋๋ค.
์บ์ฌ๋ฌ๋ธ๋ก Class ๋๋ ๋ณ์๋ฅผ ์์ฑํ๋ฉด ์ด๋ฒคํธ ์ ํ์ ๊ฐ ์์ฑ๋๋๋ฐ, ํด๋น ์ ํ์๋ฅผ ํตํด์ ์ด๋ฒคํธ๋ฅผ ์ก์ ํ๊ณ ์์ ํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ฌ๊ธฐ์ ์ก์ ์์ ์์ ์๊ฐ ๋๋์ด์ง๋๋ค.
์ก์ ์๋ ์ด๋ฒคํธ๋ช ์ ๋ฌธ์์ด๋ก ์์ฑํ ํ, ๊ทธ ์ด๋ฒคํธ์ ์ํ๋ ํ์ ์ ๊ฐ์ ํ๋ ์ธ์๋ก ๋ฌ์์ ์์ ์๋ค์๊ฒ ์ด๋ฒคํธ๋ฅผ ์ ํํ ์ ์์ต๋๋ค. ์ก์ ์๋ ๋ชจ๋ ์์ ์๋ค์๊ฒ ๊ฐ์ด ์ฐจ๋ก๋๋ก ์ ํ๋ ํ ์ต์ข ์ ์ธ ์ด๋ฒคํธ ์ ํ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐ๊ฒ๋๋๋ฐ, ์ฌ๊ธฐ์ ํด๋น ์ด๋ฒคํธ๊ฐ ์ค๋จ๋๊ธธ ์ํ๋์ง, ์๋๋ฉด ์ด๋ฒคํธ ๊ฐ์ด ํน์ ํ ๊ฐ์ผ๋ก ๋ฐ๋๊ธธ ์ํ๋์ง์ ์์ ์๊ฐ ๊ฐ์ ๋ฐ๊พผ ์ด๋ ฅ๊ณผ ์ด๋ ์์ ์๊ฐ ์ด๋ฒคํธ๋ฅผ ์ค๋จ์์ผฐ๋์ง ๊ธฐ๋กํ ๋ด์ฉ์ด ๋ด๊น๋๋ค.
์์ ์๋ ์ด๋ฒคํธ ๋ฐ์์ ์ด๋ฅผ ์ ๋ฌ ๋ฐ์ ํจ์๋ฅผ ๋ปํ๋ฉฐ, ์ด๋ ํ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์๋ ์ด๋ฅผ ์์ ๋ฐ๊ณ ์ ํ๋ค๋ฉด ์ด๋ฒคํธ๋ฅผ ์ ๋ฌ ๋ฐ์ ํจ์๋ฅผ(์ฝ๋ฐฑ) ์์ ์๋ก ๋ฑ๋กํ ์ ์์ต๋๋ค.
์ ํ์๋ ์ก์ ์๋ก๋ถํฐ ์ด๋ฒคํธ๋ฅผ ๋์ ์ ๋ฌ๋ฐ์ต๋๋ค. ๊ทธํ ํด๋น ์ด๋ฒคํธ๋ฅผ ์์ ๋ฐ๊ธธ ํฌ๋งํ๋ ์์ ์๋ค์๊ฒ ํด๋น ์ด๋ฒคํธ๋ฅผ ์ฐ์ ์์๋๋ก ์ ํํฉ๋๋ค. ์ ํ์๋ ์ด๋ ์์ ์๊ฐ ์ด๋ฒคํธ ๊ฐ์ ์ด๋ป๊ฒ ๋ฐ๊พธ์๋์ง ์์ ์์ ์ํ ์ด๋ฒคํธ ๊ฐ์ ๋ณ๊ฒฝ ์ ํ๋ฅผ ๋ชจ๋ ๊ธฐ๋กํ๋ฉฐ, ์ด๋ ์์ ์์ ์ํด์ ์ด๋ฒคํธ๊ฐ ์ค๋จ๋์๋์ง๋ฅผ ๊ธฐ๋กํฉ๋๋ค. ์ด๋ ๊ฒ ์์ ์์๊ฒ ๋ชจ๋ ์ ํ๊ฐ ๋๋ ์ด๋ฒคํธ๋ ์ต์ข ์ ์ผ๋ก ์ก์ ์์๊ฒ ๋ค์ ์ ๋ฌ๋ฉ๋๋ค.
์ฐ์ ์์๋ ์ด 7๋จ๊ณ๋ก 0๋ถํฐ 6๊น์ง ์ซ์๋ก ๋๋์ด์ง๋ฉฐ ์ซ์๊ฐ ๋์์๋ก ์ฐ์ ์์๊ฐ ๋์ต๋๋ค. ์ฐ์ ์์๊ฐ ๋์ผ๋ฉด ๋จผ์ ์ด๋ฒคํธ ๊ฐ์ ์ ๋ฌ๋ฐ์ ์ฒ๋ฆฌํ ์ ์๊ฒ๋ฉ๋๋ค. ๊ฐ์ฅ ์ฐ์ ์์๊ฐ ๋ฎ์ 0 ๋ถํฐ ๊ฐ์ฅ ์ฐ์ ์์๊ฐ ๋์ 6๊น์ง 7๋จ๊ณ๊ฐ ์กด์ฌํฉ๋๋ค. ์ฐ์ ์์๋ ์ซ์๋ก ๋ฐ๋ก ํํ์ด ๊ฐ๋ฅํ๋ฉฐ, ์ฐ์ ์์์ ์ด๋ฆ์ ํตํ ์ฌ์ฉ ๋ํ ๊ฐ๋ฅํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ฉ๋๋ ์ฐ์ ์์๋ normal = 3 ์
๋๋ค.
var Priority = {
under: 0,
lowest: 1,
low: 2,
normal: 3,
high: 4,
highest: 5,
monitor: 6
}์ฝ๋์์์๋ Dispatcher ์์ฑ๊ณผ, ์ด๋ฒคํธ ์ก์ , ์ด๋ฒคํธ ์์ ๋ฑ์ ์์๊ฐ ๋ด๊น๋๋ค.
์ ํ์๋ ๋ณ์ ๋๋ ํด๋์ค ์์์ ํตํด์ ์์ฑํ ์ ์์ต๋๋ค.
// ES6
import Cancelable from 'cancelable-event'
let myDispatcher = new Cancelable()
// ES3
var Cancelable = require('cancelable-event')
var myDispatcher = new Cancelable()// ES6
class Dispatcher extends Cancelable{
constructor(){
super() // ๋ฐ๋์ ํ์ํฉ๋๋ค.
}
}
let myDispatcher = new Cancelable()์ด๋ฒคํธ๋ ์ ํ์์ ์ ๊ทผํ ์๋ง ์์ผ๋ฉด ๋๊ตฌ๋ ์ด๋ฒคํธ๋ฅผ ์ก์ ํ ์ ์์ต๋๋ค.
์ฒซ๋ฒ์งธ ์ธ์๋ ๋ฐ๋์ string ํํ์ฌ์ผํ๋ฉฐ, ๋๋ฒ์งธ ์ธ์๋ ํํ๋ฅผ ์์ ๋กญ๊ฒ ์ ํ๊ฐ๋ฅํฉ๋๋ค.
dispatcher.emit(`EVENT_NAME`, `EVENT_VALUE`)dispatcher.emit(`SMS_RECEIVED`, `it's sms message text!`,
(isCanceled, overridedParam, traceData)=>{
// ์ฌ๊ธฐ์์ ์ด๋ฒคํธ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐ์ต๋๋ค.
}
)isCanceled์ด๋ฒคํธ๊ฐ ์ค๋จ๋์๋์ง๋ฅผ ๋ปํฉ๋๋ค.booleanํ์ ๊ฐ์ ๊ฐ์ง๋๋ค.overridedParam์ต์ข ์ ์ผ๋ก ๋ณ๊ฒฝ๋ ์ด๋ฒคํธ ๊ฐ์ ๋ปํฉ๋๋ค.traceData์ด๋ฒคํธ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ด์ญ๊ณผ, ์ค๋จ ๋ด์ญ์ ์ถ์ ํ ๊ฐ์ด ๋ด๊น๋๋ค.
์ด๋ฒคํธ๋ ์ ํ์์ ์ ๊ทผํ ์๋ง ์์ผ๋ฉด ๋๊ตฌ๋ ์ด๋ฒคํธ๋ฅผ ์์ ๋ฐ์ ์ ์์ต๋๋ค.
dispatcher.on(`EVENT_NAME`, (eventValue)=>{
// ์ฌ๊ธฐ์์ ์ฒซ๋ฒ์งธ ์ธ์๋ก ์ด๋ฒคํธ ๊ฐ์ ๋ฐ์ต๋๋ค.
})dispatcher.on ์ ์ธ๋ฒ์งธ ์ธ์๋ฅผ ํตํด์ ์ฐ์ ์์๋ฅผ ์ ํ ์ ์์ต๋๋ค. dispatcher.priority ๋๋ 0~5 ๊น์ง ์ซ์๋ฅผ ์ธ์๋ก ์ฌ์ฉํ ์ ์์ผ๋ฉฐ ์ฐ์ ์์๋ฅผ ์ ํ์ง ์์ผ๋ฉด normal ์ด ์ฐ์ ์์๋ก ์ ์ฉ๋ฉ๋๋ค.
dispatcher.on(`EVENT_NAME`, (value, override)=>{
// ๋๋ฒ์งธ ์ธ์๋ฅผ ํธ์ถํ๊ณ
// ๋ณ๊ฒฝํ ๊ฐ์ ๋ฃ์์ผ๋ก์จ
// ์ด๋ฒคํธ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
override(`I_WANT_TO_CHANGE_VALUE_TO_THIS`)
// false ๋ฅผ ๋ฐํํ๋ฉด
// ์ด๋ฒคํธ๊ฐ ์ค๋จ์ฒ๋ฆฌ ๋ฉ๋๋ค.
return false
// ์ฌ๊ธฐ์ ์ฐ์ ์์๋ฅผ ์ง์ ํฉ๋๋ค.
}, dispatcher.priority.high)Cancelable ์๋ ์ฌ๋ฌ ์์ฉ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์์ต๋๋ค. ํ์์ ๋ฐ๋ผ์ ์ฌ์ฉ๊ฐ๋ฅํฉ๋๋ค.
์ด๋ฒคํธ๋ ์ค๋จ๋๋ฉด ์ฆ์ ์ ํ๊ฐ ์ค๋จ๋๋ฉฐ, ๋ชจ๋ ์ด๋ฒคํธ ์ถ์ ์ stack-trace ๋ชจ๋์ ํตํด์ ์ด๋ค์ง๋๋ค.
dispatcher.emit(`EVENT_NAME`, `EVENT_VALUE`,
(isCanceled, overridedParam, traceData)=>{
// traceData ๊ตฌ์กฐ
traceData.stopper // [1]
traceData.listeners // [2]
traceData.override // [3]
// [1] ์ด๋ฒคํธ๋ฅผ ์ค๋จ์ํจ ํจ์์ ์ถ์ ์ ๋ณด๊ฐ ๋ด๊น๋๋ค.
// [2] ์ด๋ฒคํธ๋ฅผ ์ ๋ฌ๋ฐ์ ํจ์๋ค์ ์ถ์ ์ ๋ณด๊ฐ ๋ด๊น๋๋ค.
// [3] ์ด๋ฒคํธ ๊ฐ์ ๋ณ๊ฒฝํ ํจ์๋ค์ ์ถ์ ์ ๋ณด์ ๋ณ๊ฒฝ์ฌํญ์ด ๋ด๊น๋๋ค.
// traceData ์ ํ์์์ ๋ฐํ ๊ฐ ๊ตฌ์กฐ
traceData.override // Override
traceData.stopper // TraceItem || null
traceData.listeners // TraceItem
// Override ๊ตฌ์กฐ
// (Override ๋ Trace ์ ํ์์์๋ฅผ ๋ชจ๋ ๊ฐ์ง๋๋ค.)
traceData.override[].isModified // [1]
traceData.override[].before // [2]
traceData.override[].after // [3]
// [1] ํด๋น ์์์์ ๊ฐ์ด ๋ณ๊ฒฝ๋์๋์ง ์ฌ๋ถ๊ฐ ๋ด๊น๋๋ค.
// [2] ๋ฐ๋๊ธฐ ์ ๊ฐ์ด ๋ด๊น๋๋ค.
// [3] ๋ฐ๋ ํ์ ๊ฐ์ด ๋ด๊น๋๋ค.
// TraceItem ์ ํ์์์ ๊ตฌ์กฐ
traceData.override[].functionName // [1]
traceData.override[].lineNumber // [2]
traceData.override[].columnNumber // [3]
traceData.override[].fileName // [4]
traceData.override[].typeName // [5]
traceData.override[].text // [6]
// [1] ํ์
๋ ํจ์๋ช
์ด ๋ด๊น๋๋ค.
// [2] ํ์
๋ ์ฝ๋์ค ๋ฒํธ๊ฐ ๋ด๊น๋๋ค.
// [3] ํ์
๋ ์ฝ๋์ด ๋ฒํธ๊ฐ ๋ด๊น๋๋ค.
// [4] ํ์
๋ ํ์ผ์ฃผ์๊ฐ ๋ด๊น๋๋ค.
// [5] ํ์
๋ ๊ฐ์ฒด ํ์
๋ช
์ด ๋ด๊น๋๋ค.
// [6] ํ์
๋ ํด๋น ์ฝ๋์๋ฌธ์ด ๋ด๊น๋๋ค.
}
)dispatcher.emit ์ ์ธ๋ฒ์งธ ์ธ์์ ๊ฐ์ฒดํํ๋ก ์ต์
์ ๋ฃ์ ์ ์์ต๋๋ค. trace ์ deep ์ด ์ต์
์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
trace๊ธฐ๋ก๋ณ๊ฒฝ ๋ฐ ์ค๋จ์ ์ ๋ณด๋ฅผ ์์งํ ์ง๋ฅผ ์ ํํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ต์ ์true์ด๋ฉฐfalse๋ฅผ ์ ์ฉ์ ์ถ์ ์ ๋ณด๋ฅผ ์์งํ์ง ์์ต๋๋ค. ์ด ์ต์ ์ ๋๋ฉด ๋น์ฐํdeep์ต์ ๋ ํ์ฑํ ํ ์ ์๊ฒ ๋ฉ๋๋ค.deeptrace ์ ๋ณด ์์ง ๊น์ด๋ฅผ ์กฐ์ ํ ์ ์์ต๋๋ค.false๋ก ์ค์ ์ ๋ฌธ์ ๋๊ฑฐ๋ ํด๋นํ๋์ ์คํํ ์์ค์ฝ๋๋ฅผ ์๋์ผ๋ก ํน์ ํฉ๋๋ค.true๋ก ์ค์ ๋๋ฉด ํด๋น ๋ฌธ์ ๋๋ ์์ค์ฝ๋ ์คํ๊ณผ์ ์ ์ฒด๋ฅผ ์ต๋ 10๊ฐ๊น์ง ๋ชจ๋ ๋ฐํํฉ๋๋ค. deep ์ต์ ์ ํ์ฑํ ํ ๊ฒฝ์ฐ ๊ธฐ์กด trace ๊ฐ์ฒด๋ ๋ฐฐ์ด๋ก ๋ฐํ๋ฉ๋๋ค.
dispatcher.emit(`EVENT_NAME`, `EVENT_VALUE`,
(isCanceled, overridedParam, traceData)=>{
for(let overrideIndex in traceData.override){
// deep ์ต์
์ ์ผ๋ฉด TraceItem ์ด ์๋ TraceList ๋ฅผ ํ๋ํฉ๋๋ค.
let traceList = traceData.override[overrideIndex]
for(let traceListIndex in traceList){
// for ๋ฌธ์ผ๋ก ํ๋ฒ ์ํํ๋ฉด TraceItem ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
traceData.override[overrideIndex][traceListIndex]
}
}
}
// ์ธ๋ฒ์งธ ์ธ์๋ก ์ด๋ฒคํธ ์ก์ ์ต์
์ ์ ์ํฉ๋๋ค.
, { trace: true, deep: true})๊ฒฝ๊ณ : ๋น๋๊ธฐ ์์ ์ ์ ํ์ ์์ฑ์
๋น๋๊ธฐ์์ ์ ์ฌ์ฉ์ฌ๋ถ๋ฅผ ๋ฐ๋์ ํ์ฉํด์ผ๋ง ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ์ผ๋ฐ์ ์ ํ์์์๋๋น๋๊ธฐ ์์ ์๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ,๋น๋๊ธฐ ์์ ์์ฌ์ฉ์ ํ์ฑํ ํ๋ ๋ฐฉ๋ฒ์ ์๋ ํญ๋ชฉ์์ ์ค๋ช ๋ฉ๋๋ค.
ํด๋น ์์ ์๊ฐ ์ด๋ฒคํธ ๊ฐ์ ๋ณ๊ฒฝํ์ง ์๊ณ ์ด๋ฒคํธ๋ฅผ ์ค๋จ์ํค์ง ์๊ณ ์ด๋ฒคํธ๊ฐ ๋์ค์ ์ทจ์๋๋ ์๊ด ์๋ ๊ฒฝ์ฐ ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ๋น๋๊ธฐ ์์ ์๋ก ์ถ๊ฐ๋ ๊ฒฝ์ฐ ์ฐ์ ์์์ ๋ฐ๋ผ ์ฐจ๋ก์ฐจ๋ก ์ด๋ฒคํธ ๊ฐ์ ๋ฐ์ง ์๊ณ ๋น๋๊ธฐ๋ก ์ฆ์ ๊ฐ์ ๋ฐ์๋ณด๊ฒ ๋ฉ๋๋ค. ๋๊ธฐ์ ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ๋ฐ๊ฒ๋๋ฉด ์ฑ๋ฅ ์ ํ๊ฐ ์์๋๋ ์์ ์ ํ์ฉํ ์ ์์ต๋๋ค.
dispatcher.on(`EVENT_NAME`, (eventValue)=>{
// dispatcher.priority.async
// ๋๋ -1 ๋ก ์ฐ์ ์์๋ฅผ ์ง์ ํจ์ผ๋ก์จ
// ๋น๋๊ธฐ ์์ ์๋ก ๋ฑ๋กํ ์ ์์ต๋๋ค.
}, dispatcher.priority.async)์ ํ์๋ฅผ ์์ฑํ ๋ ๋น๋๊ธฐ์์ ์ ์ฌ์ฉ์ฌ๋ถ ์ ๊ฐ ์ฌ์ ์ ์ ํ์ฌ๋ถ ์ ์ถ์ ์ ๋ณด ์์ง ์ ํ์ฌ๋ถ ๋ฅผ ๊ฐ๊ฐ ์ค์ ํ ์ ์์ต๋๋ค.
// ES6
import Cancelable from 'Cancelable'
let myDispatcher = new Cancelable({
async: true, // ๊ธฐ๋ณธ: false
trace: true, // ๊ธฐ๋ณธ: true
override: true // ๊ธฐ๋ณธ: true
})// ES6
class Dispatcher extends Cancelable{
constructor(){
super({
async: true, // ๊ธฐ๋ณธ: false
trace: true, // ๊ธฐ๋ณธ: true
override: true // ๊ธฐ๋ณธ: true
})
}
}
let myDispatcher = new Cancelable()Cancelable ๋ชจ๋์ Node.JS์ EventEmitter ์์ ํธํ์ ์งํฅํ๊ณ ์์ต๋๋ค.
- ์ทจ์๊ฐ๋ฅํ ์ด๋ฒคํธ ๊ตฌํ
- ์ฐ์ ์์์ ๋ฐ๋ฅธ ์ด๋ฒคํธ ๊ฐ ๋ณ๋ ๊ตฌํ
- ์ด๋ฒคํธ ๊ฐ ๋ณ๋ ๋ฐ ์ทจ์์ ์ ๋ณด ์ญ์ถ์ ๊ตฌํ
- Capsulable ๋ชจ๋์ ํตํ ๊ฐ์ฒด ์๋์ฑ ๊ตฌํ
- ๋น๋๊ธฐ ์ด๋ฒคํธ ํจ์ ๊ตฌํ
- ๊ธฐ์ด ํ ์คํธ ์ ๋ ์์ฑ
- object ํ ์ด๋ฒคํธ ๊ฐ์ ์ ํ ๊ฐ ์ถ์ ๊ตฌํ
- EventEmitter ํจ์ ์๋ฒฝ์ง์
- ํ ์คํธ ์ ๋ ์ถ๊ฐ์์ฑ
- ๋ธ๋ผ์ฐ์ ํ ์คํธ ์ ๋ ์ถ๊ฐ์์ฑ
- ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง ํ ์คํธ ์ ๋ ์ถ๊ฐ์์ฑ
- ๋น๋๊ธฐ ์ด๋ฒคํธ ํจ์์ ์ ์คํ ์ดํ ์ด๋ฒคํธ ์๋ฃ ํ ๋ค์ํ๋ฒ ์ฌ์คํ ๊ตฌํ
MIT License.