{"_id":"tame-search","_rev":"36-5c089332f04305687366804c28f54122","name":"tame-search","dist-tags":{"latest":"3.0.10","prerelease-3":"3.0.11-prerelease-3"},"versions":{"0.0.1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"0.0.1","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"e8078d4e5f2cae1e95651e8f07d86f84b9b3aa2c","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@0.0.1","_npmVersion":"5.6.0","_nodeVersion":"9.10.0","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-7aRaOQmgxekw4J+T1Xia3A2Ycx3XsgNffhZl0ITAVOx29J1AwUgdVnt3IOYOtZk9g0PeBbmWRpBJbx9NCx+/Tg==","shasum":"0cec15709110792cd182f8cce32ae791d513fd1d","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-0.0.1.tgz","fileCount":8,"unpackedSize":17211,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa2vNoCRA9TVsSAnZWagAAnT4QAIaQKdbjZ7B0CVZg0npg\nhvKS3ztE9UAoS2zIOdoMq3ZDR+Zfb5LYLgRMt15nRhQ2U3WRw8xuEdrl30yF\nXJb/Ta4xD9aI1HFyu8heazLNqfwAXqngv+wNlbh3grKiSwxuszCwRTKa38Wf\nk3H35V6AgJY++H3jFhdV7hfIzojkJLmoLgtXH4jwjgg0gm39cfgabRDZIfZ4\nGCEna67131mk5PdLIaqwBhW1RdLJsHRT3khLpG1E8pl9Yg+Iru9Wh6z1lccC\nClZKjbT0NR34Nu42Hv90cKZiNzgfvsQ4I/rpzEzU92AjQAtPHTJ+RZSnFrQO\nQkrHJPTLqSwHuGPSAqddloik3iRCCstw2zVpdhnCHij4q6/7vAdEPIaiw1+G\ndpnVhOEpOvPU+AmfLHwUcOfgpNuaLYBOmBUhT4zveDsp6gH+bDGrPyoO5X6m\nvyUaoI/LubeJtOC5OcR939esf7Alhe2mGpLzGlQLm7HzlCAGBsjmImgMpUf+\nep9KHzFsXgTaQnWo4Rc7ett8zbiNMIhPzRr6ix95HJUTHCr7/gkwIiIYMdmE\n7WyRf5qWpIYpCpM9B9tKmJiokUekP9o/TM+alobVZewy2yQlbY3kWfGdF7KG\n1WoKGRdqARcvAedGMZDWapaW42l707Yb1SjhpS5eZ4sInQyrScZGIIKhUHFF\npjB9\r\n=yiCp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCefQU+/QoIBrUg0ny8dtrrJ9dWXSoWVbYADGHLcFgeOAIgZgtCC4jQZ/62GMQyoDOctEQBc6QLaiNArNHAdlHCP6o="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_0.0.1_1524298599218_0.6289558703050266"},"_hasShrinkwrap":false},"1.0.0":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.0.0","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"3e04b8fbd54a4987e67e325fe2a6b0e59fdafe54","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.0.0","_npmVersion":"5.6.0","_nodeVersion":"9.10.0","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-Ft7O78FNPqQ7ajiBuwC4BPvDrL4eYfR477REBrr9ZtOTHgBMNVF/OGcZEu/kJSXg7FD63IFmkU/ErJLstp0Ilg==","shasum":"539d92731973ef0bc4aabc509d8a80a6d977f029","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.0.0.tgz","fileCount":8,"unpackedSize":17289,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa3FKFCRA9TVsSAnZWagAAM2oP/2giLLolQo1NW5SORXAK\ngFhhpnnW5cYW6iNbwllpAJfK/39x9vxCwtvUUpic/5O4w9CnMsruQMTGq/3u\naqhMc7u6BudxMUNtJKj1dayZiBwgVnjs9kxhndk4DOG9+0ICzj7gQTHRATAn\nROZ3igb3fD5x7sA8z83JUaO+70FFazwvgKXBnNYIDHKPVRK1a7YsiIas9Vyc\nkfSFyIF/GciaMAKZf39rqU63Ro6VsLS5W8C8H7Z+7+GfY475cnDQAt8wA6m9\n0yEWPgf0dNfMqaRJJFhtz46lcSzA9p0wmAajnLvu02xmlwvXQ7uSliEfLEKg\nB5hc+I+iaPvPxLb2TUM1zw6pzPfPttmkf1j34Ktac0dK/iBjMvS8O+gqLY/8\n8lPPnPB4f70XBxqIpJo+z2y8Xzc2TAdTLg4bn+GL56Ys0bXN2FojjhCpHkfK\nP5hDARCFkFVdp/ey5j9Yiu8/fHxAeYHVYCsKkysuvK7js8BtxBswkwOD02YT\n08ER/yD2BswBN7xW8Gv+3S/OSKJiZ6jDsZI4iQGBUIuFziAso6a9OsFa/Uvf\nP6mSLshR+U+eq49UeOApli0LiokXXkXOvSV4DKfKt8B9tSymnicvm1jcwp17\nMlrXgtgAsIA4XdvZn29+05obyrPV10ssb8V8YVvN+JoMfMS54QFDHrAZkLZy\nBygW\r\n=hPGQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDqePaI8pRFe8UFdhzEKN26UklSOUct6vbWLNAbUl2nLwIgQycpyCPkr/tIt641CcR9xbSgn8Ls/LkYsGbM3NDm0V4="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.0.0_1524388484469_0.39121481457693186"},"_hasShrinkwrap":false},"1.0.1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.0.1","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"f0a7e1e08633c54c8158171dd250a9cf4a9ea865","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.0.1","_npmVersion":"5.6.0","_nodeVersion":"9.10.0","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-jHVANuJkAwLfuiyUeCjP3wdJ+lm6ORq8hM9OOolboQMR2Jk22P+9sXsG2nPHsE05nUfEFwPzjZJKms8xBA54KA==","shasum":"a6606817ee116503bc7e98d541bec3320ecb7b54","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.0.1.tgz","fileCount":8,"unpackedSize":25906,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa9BDKCRA9TVsSAnZWagAAud8P/A6KNQc+oDAaxauJUfvQ\nELL9ruSV0g1oA8kHIcXGJsAEIq8WHdWVvL2Lb8INRoSwJD6PZpKr2dIz9suu\n4bmKlx9LPAAO58x0f60GDjxpAnPXIpfVmS+I8Y7Gw836ZDtY3Z6CJ3uiUV1j\nr5RDUQAAMB3E3IveB9RhGFUoBAUgK5eu4v+mg2FsX2dt1FVFg/ipJ3bet4g8\ncRh0282cd6Y5hKHg66MQrY6g/KBPMisp6BXkaFr8K1p3ZVMgDsaOZ9tYUKQm\nSmVcFyFuX43c0qalgymMSN+3VQ6zGuOgsqoOON+w2ZjudZ2aH3z7jpo8NWWP\nggYlixGXspALdggHlrgKQNRCt+nS/XBggS1nw7q/7KZsVT4t95hUzbXuXPkZ\norl37IpPj83CMMfmpR/BShAfsKzLdfk+24VN0zYir94RZUv8vIJ+QkrRMgXx\n74fCV3y0Grp9DcO0iePdz5r+dFdNr8id82dTFP1jAZyu+h1HpUBTrgmYrIol\n0meazcQmgqaP+l782dForUuV9a6EySEqYqbYuuE3mmgB4dK3ai6QWoZPsVXQ\nidqchzppDs0/nzAqCdt1Jzl9XG6pEO/8QnWyCO3NVqIqXgQM0NLukh5maIry\nEgmhw78Lw69hVDc4WjceAllP61AGy7xsY89uMOBGRjX87rQAVS91kSFTsF0D\nN8tW\r\n=6mYl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDNJVlfOLtQkLc+4/QriZSSiVqz+aZ1xZ4Iu/nDCzRUZgIgF9nQ7H6CUVR4uemBmYBP+M2sKrDhtiSD5knWB2n2QO8="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.0.1_1525944522354_0.5157018801431517"},"_hasShrinkwrap":false},"1.0.2":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.0.2","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"83c3bc5a629b7a0fc5e019d6e4a1eb5e27ffddc3","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.0.2","_npmVersion":"5.6.0","_nodeVersion":"9.10.0","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-UAazNvo1EQT8uPJ9AwgSYYhjeNwHqNO6AMymUwM9mWpYVj4b93tfoJVu04pmTBKsm63K8q5mZhA2VrTH/8sPGw==","shasum":"d6c2c82ee195ed20b86576c9eab1a7c4aa39b68c","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.0.2.tgz","fileCount":8,"unpackedSize":26050,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa9BJ5CRA9TVsSAnZWagAA0Q4P/jMu3rKMz9wU+2vFHgs+\ns7nYnTiYHSmMq8FTgHjdNp8Qw6U3QTz9ZdNa/QDKwNyfUEiS9t56EJbbfzZf\nGF5YYyh7qZv+x0tZtGFTNPfShJXy3b37sBLZSZyvVuO9I98bvt/LBsqF/KK9\nW4jJAdJOSfaIUzWXX89IuJzOizHQHwZgKUlxXI0R6+pv5PrtPdxw/xRk1A+c\neHMYdRAZBVoFFkKb6tdpRtNqPBCiV6xaqD5+Fwnfc3Nff6IdYPudAkw+rn0P\nFUL9Fe6Y9ZLeXEQtWmhA9ebYxnZuqXabEfjRNMHCcuQAfN4NEBA9qv5B+Ku4\ngGARzmhdyjTD1iPkeeCEG8PpFiIGaj82b4xGOVt6doyjWjU1uSPiv67Lf7g1\nh0bpuns45Vy0mnxuZGpvxoBAsxU1JqbxXukoDAG2A5Z4gIIz4se+ESrqvgYN\ni6FPHbjymY71ibW2wu5xsSXhHDovyMgUcXkdKou047d+sQTzOpinuutCknNX\ngfJMGSTHDJvM8SuzInV9mTjF/gnpe2cCfYsjCYTwVFHwr1sW0CYx2uhGKEyH\n0dcBWZYmZpsDUxkAelP36OhI8w8hZhR38zWiK2quFBrSqNEqOF0WFO9tQx0C\n+RrrCPqNtzttH6VnrNP1n9jvfc56NbWj3nPBa56h4hX+zQ4XK6yeeAq3Cp6H\nLN2v\r\n=2d6Y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGSbTMNV7JjbbJ9ejkEJiTVUIiZM3IkJCpbwVWXOargTAiEAgU4YyK4MA+t6bTdRaPDO1mjy6224Z2ILA0H68mcjn5M="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.0.2_1525944952090_0.11269815001396433"},"_hasShrinkwrap":false},"1.1.0":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.1.0","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"a2fe00dc91f948e9e21078fdaa48b5564b57d068","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.1.0","_npmVersion":"5.4.2","_nodeVersion":"6.11.1","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-/tV1tHkq/LkVpr/6Su2OlN+30Gso45LNFJvJBZp9jdWlgSWVmWon0X/DuzZ7snowz4BBlyTXZVMzOXAYNBZnFA==","shasum":"0e6fe1499beaae6b00e04b40ee4853b0741437f9","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.1.0.tgz","fileCount":4,"unpackedSize":13251,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbkPMPCRA9TVsSAnZWagAAuEgP/RWurDpPiNMCOlRj5kk0\nJevvhTnz1Pm7pJCNh/fZWuMmtuZLWygbDs230asvx7QCFRGZ+szAaN/pCWzM\nPfQ6VzvdnX0kj5V0v4K32Uaf3OtfPFKUuuUuoDowRS/egJ0XUE75Jk66lHi2\nsRDz9fsOVxJgBTEXunM1XXxJcAIriYmHmjeRpcVqo8IVdTGLNmbM4HtlQE6A\n40FTkbrjhnMR4LCOAOweYm2GvJVGtW9K0gh1hSm9Q3bZOA07xS41dSBD1oHb\nhI7iiXoaiNXOhA/fmDS3Cqx+L8HAGoHs/gmIctBLrgHkGFxGSQoSgo+z/Ayz\nXk3Qu/RrOdaIeb84WDfVREcChZhA3FbVttXEjY3UqXUJ9gr7M+LrKSmr4Ooi\n3wPW2+UHA3NdGzmYF+FP4tXbDd8s8BF2e41023/EZHf8WhRjd29jmJUXVqN6\n9nf+Ya3g3Hcl6jTCZ65rDnCyPbxRUjSwbzSBI3K0VQIiRQlD5qMmfWzU7ioX\nvKY18Diip3Fl+VuocKdCJQuQlgLJXpNOUMk4lfC+G57SX9sxxpmyMxBnQqYz\nAKJk61JkWvKuUZm8Gl4UaMHw2pTsHefXtiY748L5MTjZ6xCCmGMmuf0O/gPi\nz6XNYUT+mf1ZpXUM6c73flGU5NzSb5Vb/PB8EYWgcdZqi9ye8WY1KGanF8ze\nu3va\r\n=VsYs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHdEmzH6P2LiAWKX6SBPJsoiNxgAwaNy0Stq+0M/M3SqAiEAiehjMK7P13voiRee6j8UFf3ZU57mxocyJ1at+EAYaJQ="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.1.0_1536226063231_0.7273827186003856"},"_hasShrinkwrap":false},"1.1.1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.1.1","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"1fb7ad616eb4e631f6275415e918d80c2eccf310","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.1.1","_npmVersion":"5.4.2","_nodeVersion":"6.11.1","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-eZ5K4VBsPH7qkTyw3mtieQ7xs1OlJTH4A7+U+jUM2geBYZBFrWYR+Rn5aRNljlv5iwXdEPPYCbms9iUQSBIwtw==","shasum":"51fa185170e4d77c2a40a85c3fc45f82fd1bafb7","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.1.1.tgz","fileCount":4,"unpackedSize":13599,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbkRORCRA9TVsSAnZWagAA6vQP/isinU39lh+JmgpMg10S\neFfgdJRZ5bWWUHurV6JAzIWmdgipMoskifNYSSJ4Wuw20zHuFi1BcJZ+mZ+U\nKgt7YytCsmAAWZfPq4r9Bp4eSujyGAT4LXpRz4FItGbIu6zBUupVUquZnORS\n+3FI0KNAn1x1bkFb1bQBpr3exSvc4o54h9GU8Ecgx/DrZfYgFtdSgL0qnUUB\nfyCHcFUZJd1zVAqyJnd+Ho2Ee5o6hrJVGASivhW5WDGdDmH/BIY1wN+rW3s3\no/lrvTRgfMaIvDSQgKLMfDilCBH9UMMddWHZ0q6E++b/CKJEDKmLUejP7GAv\nZI/3EITXh/c2Mlhd1CraFA6HnXIp8guJFHvCL1Oqc+/48PbFPR5+l6wNp1Bb\n5IdcqdoxiiFxbgjgpUvuFmK/+NWxQt4pDra6xpDSdczdDwn2jtjue/R1q0Q5\nwUZh0xBuoAYcJ56rkruGqShw1wb66sTCvKT3SIbLKBdw/5yjPjO/StnNIiMt\ngLcCbNJlITEaNsIj+ciVIdBwPMy5Uzce50my8oQZWkM/YIUuEnIMfAb5+LDW\nD2iIz0VVmbgO0pZvIjCQUh5b458Epd+iUUXpwr4FFjFDxqapu5obG2ZHii1f\n9f3Fk7+I0p950ch2uCTx9+xoSHK6HG/IVtB61y27mzl88cWBqfNlhp15Lksj\nlWwv\r\n=FDI4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGztZ28cRqLT+DpcbHRl/bFjPNvBYntIZ7VMnhpv2VMIAiEAoMybBqI2hMA/7CcDUTGzPCvit9W6SuOJL4li1nWkVEg="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.1.1_1536234384335_0.5229230190862049"},"_hasShrinkwrap":false},"1.2.0":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.2.0","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"f3ee0f353ab5836013f28849d43e17cd40b1c2e3","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.2.0","_npmVersion":"5.4.2","_nodeVersion":"6.11.1","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-hFf/4PNSTlYLQ9ED5KpUb/omIUhTsw5Ip+jmByIFWHicP3Q/ba+ZotBTR+4sW1v4FPCVnTixGsv52FLi1fpfmQ==","shasum":"40720fa4ea9ba22860ab09e91eb33dcff1d54551","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.2.0.tgz","fileCount":4,"unpackedSize":16886,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbkTMtCRA9TVsSAnZWagAA0b4P/igqiUN6N5LPfDBZU1cz\nEA2SjEhyaAONCuozqvb2I/8DN/QsFp0sSLcaEAAhgLKAa+2QOYqxSIdU1Y5o\nPDqbJSqhuUftUmLJFyvkpQuxoqmqiUK8irBJon7Ulfkw/+ZyrKz8a3JX7NFW\nMsU026llW9jZUr+Ca0HKVRsuwvRhCoc+0zEO7w/jM3rf2Dkmk/k5m/e1y3Ys\nFPLoIbWSSYWDvmngtPUFAUCr2R14PVu1cB4Cf8LTlDDC3rZoULBRxDtKOdNz\np/sATo8adFd5HrCDc8iwL2Jd5IQ9PgObpGNLVC4auFTAZonnHgNSDlDm90ji\nI72lpMFqFSx2Sm85LWcAF3PCwYFMIu1LSnBSP4xq5Mwvb5TZzAQjGKYjskPp\nS7e/Hwd8Hm2EDCpUfjrk4YXe53/pEW8EcXw9D6Q0qe2uugGo+83weuLp+0er\nAaEDWNOeIUPI+wG7rePHs95Q7R+iJ/zDpjEuNQnbanMTEomHYFarB/jhIYvA\nwBjBtdRct390fF4cuabACZSmmjyFKXsb2tDOpTe4hvgMoZyW8224OhvJaApa\nGbO4fJf8imMg27rh6T/koMiKecFhVsNOsmJShMfxE/tVyx2+eTCBk2KFsJWf\nCzR813pI6VLGaPhnfTcZMvDsTPJFDBYWbsp6KTya4MNWOkSNrMP8vOpcag6r\nUkaQ\r\n=4PSI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDu2Xpe84e6P5m5RacEPouDXFDSTityLBL/uhOlzm3ABAIgK78BYIJ8tyjHlTN5TnHPCo1SYu4ziGrnlqAlh4JF9cM="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.2.0_1536242476627_0.7107049280600359"},"_hasShrinkwrap":false},"1.2.2":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.2.2","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"d3bb5e55e08c8a354950a148983e16234ae407e5","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.2.2","_npmVersion":"5.4.2","_nodeVersion":"6.11.1","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-d+9oYIhkt71JlOWsk4gemWYdzs79cmWN5SWKnCO/Qkm9iKB+HkydXW43hrEF85l/9WeM1ML1q7RI13yzACi1pg==","shasum":"3c81b06a328033deece0b1e134b4aa2baf7c6ce8","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.2.2.tgz","fileCount":4,"unpackedSize":18324,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbmgyECRA9TVsSAnZWagAARU4P/24eP3pK5pgVXJ/Ne0OR\nOaI/ExPBg2wNApu/vRgD3k990C2P1qrEYmyXXI79dk43YsiIjBtcCHvEkGkj\nW9b2WrDX0AAOsi4JQaXJJR2eTR0/EmGpdYqxbBrcFVvIkA4IQ6frd4QLmOWg\nJ0RTbmMRSMhTlQh9O3ET99qQ2kTT2vOAkGYs/92QPXZWqCD66q5U35Cr8KR7\npZmpX0hEyuJKk5CzRWp7RQGJWe+fX9z9HszVnHYZZFTmrmlD3kmVlYQVI+Tr\nLm7tbLsS4o96DvKfDTCkTcpZWzbKWnx9jQ6CZh/w835MWRg8ManypC/W9vem\n5udWzM23Kqd0yBqIyJK6BXYmv6McwZhOhtepgQpH+6CKJ4Wi2IB2lBdcTVkp\nDQnY3xfx+/EKDbJwGKocu5JZRDYer2B27i40Fokq5H2Zqv5QtjaLVtAqkCBT\nUU64OlNaaVErpH3wDrDAGjdskaE9OFmybpTw4YuGs1h+KM/2QufSVN05ZpZ1\nkwZAenBsCF9d5FBf/X234JwXLBK7jcnUNxVxb8GIFbrJnMgafpGKi6geEN/5\njwzatiq399MwKL7zWc6EF+kSiVgjVvkqj+P4SF0Ak/N2i/4kaDXFiRueo6zt\nYsYiK7SUxX+9oYMf7MCTT2KhevDZMuRfE5sOCb9ZcbprfbaSgE6fBq+hTr95\nsZ/N\r\n=yezG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBHzU9nE3cH4xWnPcYsFzmxqAjYM5Vf0GYESuBEuu5RSAiA2fgOuDw1YZmHEs5Pn8mYqN2vg2atTrUH/xn21Zjg+ww=="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.2.2_1536822403828_0.012238536306826475"},"_hasShrinkwrap":false},"1.3.0":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.3.0","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"4fd909aedc6c71dc4e4c2067a97dc8a20c93e30a","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.3.0","_npmVersion":"5.4.2","_nodeVersion":"8.2.1","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-Jb/2NkNDgWi3QNB0m9vL9fqXyvvsQWntBGpG60yOQatsAM2EuT1EIkYrUAxkhY6bolPrptTya2lJJ0AuxmSZVg==","shasum":"f837f769f845258013f39e823d87f14e6353d4ba","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.3.0.tgz","fileCount":4,"unpackedSize":18785,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbq1z4CRA9TVsSAnZWagAAbzgP/idJqfXBmlU/VqkNJ5ux\ns05E4/FrWqX1fNRi0v210vIwkNgtGkrlEYdQQ3htk2RmHhV09dCn5q5rntBr\nUExlYdWEKjmbqN57qAl+dmvI9pUSXvJZXey40xDJwnUdos2U3PO8tgo30AD5\nkWp7dB7Cwmzqu/6dy4bMclqenfwCfcdS7YaX59JQjxv2SlCFlJCZC/9T9UaK\nyhgTx21/FGaUKEInPkRnNI/Z0CThv1KFrn+f4CY27n2w05hT7kcG/KFYasUq\nf2/LtGi+VxjUzoYUcDtE7YtpBRFS1+IlWZrm4vnPvBSImyn7+S3cnhqlZoqH\nRYG9hjZNbxGh8YfwpBZg13WUPGcIE+hptMdTWdHTl6HoirDtFEeWXp1mrrQF\n23umvoqBpqGvhWee7Xy1aEPNrJgTjll5OY+DFTm/3ICCovD0Y7ROMMY1Ob/2\nvSp1X2TEqJQ9jsgRy+fQ2kvS1rpPHPChtofdTf6+nHI/xt2/xOQpMUMd3L1B\nToDare+Hxx9feMTMIZ5OVCgFRDQio+jDjGAf7ywhkeV95nl5aPeC43dj3a7N\nM/YCaQ7hF7JIlD3SRk6z5OnkV5BFlzS30OrrLomBJjrJEzL2R5xrzWOipqlc\nKIiUUvayMShP+yR1+lsa0426KHUBrzYL7TBSU/v7oL3b5dkq0xBg4XvRMGX/\nOYqi\r\n=rt68\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEW/tfH/zOq3J088SD8Gx2EBYcqKUyvhZ/fgZ2VIfKyNAiBQnntFHy9aXyXyoujZ0+Xogza812ZLpKQII+OCC5MYXg=="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.3.0_1537957112205_0.6545548297310473"},"_hasShrinkwrap":false},"1.4.0":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.4.0","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"eda83a8ea1a5da5773408ba174bf4279f217a5fb","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.4.0","_npmVersion":"5.4.2","_nodeVersion":"6.11.1","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-Hdj7ZPyWtdlH7XeKBydOLjArUOOcQFeMEtCM2aT2GrnpUZO20HV7JS/wl5V4QDnlod82uA4B92p+EXAxfSU1Ew==","shasum":"29808044afcde21ddb35218e63205bf55301f8c1","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.4.0.tgz","fileCount":4,"unpackedSize":20419,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb6ui8CRA9TVsSAnZWagAAZpkP/jTFP+G6kj9ShuF75ddP\njlsFdt2IodSGX8E2ZE1riKN9+1qNs464OE3vij2fupuqveVa/kt6WDEHsMjE\n64N52l8jmI+DN0gIIc562WKKVDV3dQpNEniO1dQ96FUqiL95/xfZyub5or/f\nB9Q7avjab8ksm2zkKKhs8CZNq+87P19XOC6D8mW119ECnPMHPMrxCHT61oPI\noD9WkYUuGJpkwaAmlIbqW74xy+9kWazA8MNbLcVYecl/iEaeMIyeUOc/5i3Q\ndH2L+WwbhBiTtUJ1j72QcL8YD8dGLbz7cr8ZwMmdZakoihuvldfeSMenXTjj\nuNtjy9sYSOulk4GtJ1tRq41EFLbHn3Wn6JQot8pva3eLSWiMphJrYd9fXmvC\nLEjQ6GHjqNuVNy9mDIsAWAjegrX8s+DkLxxipLQGEijAEnhdetLNlCZIKpqM\nfvB6bBFXI+U7wC+7uOIM6XPhR69KFtvwwu6odou3GQZOvNIKKEqp8uOcpO6Y\nQzP3BoX9FovX1tWSuFLY2kcUrwka4WBVTxr5XAZa9Z4ZexsJvy6CRr99pYdy\nuwvjyShLcxAW0vUPq4OiuRw43UJqvXXxLbU0Nmrn5+uUshSartD8swlcojPd\ncjNlptHeaIwkYsxtR/2PC3/zRAvgDjaKsQvDYHDZODkDE/wtraFprxrkyqCl\nrLjC\r\n=auNw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFxiMclLFM2tWo/E21s9iVQ5CzU4LAUwLzCIQr2vPWCnAiEArhamyRwSkgCNAbW3Cf1zHlyh1OLO0XwxVaxVZt0WStI="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.4.0_1542121659916_0.804536633652535"},"_hasShrinkwrap":false},"1.4.1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"1.4.1","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8"},"gitHead":"7f641b181c7d01ec96e6c141f8ba7f014749247f","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@1.4.1","_npmVersion":"5.4.2","_nodeVersion":"6.11.1","_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"dist":{"integrity":"sha512-F5XUqH+tCrgo6zFhqzYHo//zyltQpccyY3hpQy4dt0T7hfcGsDYHrZxpSEeQ70HYSuAt4IYB5JwtWtXHi1yojA==","shasum":"7884f13ce009066a61d06130d1b93ce7af24e398","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-1.4.1.tgz","fileCount":4,"unpackedSize":22348,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb6wNKCRA9TVsSAnZWagAAncEQAKExXJ1DkpngSDMHSbxr\nQfXz6XXsH17cUhe8iwqLhLOqUhWjEBU9mreXYmszf62fRYHQevkBR4mL+Ctj\nbkAVWif0Jzvys4i9jEY5Go3xmAG3cAV1qMr41gG3texhWLakkHKGN30yyogu\nE0NG8gSnzA1YRzpc/vB5VRnhNbaVa6HdtiOCB+Aj7mR19lrUDBEhu6lamWr5\nSlW0KcX5ZLRYLZVLDgnbVfTIDsRifP9zeb10N8pJozJkpcOEGXEnl52+2CiO\nX5j4Vay/EmiYjg+jY5LYGf9zGEtR9K89OpPlP9KJk1wXNd4k/tQh70KqF/xO\nq01qDjbP/p1gjWUi468BAd22jKKWjSAtDXlyM9gv73TewDG2G8e9okJOcVza\nZ0XjxG7ZHJg2gPA1n3psUp7//vn69B+AVbU0NEkams3boejjdWwyfhQB7mBP\nV5raqanZQfl37WFBfT7auKyBChWfneQp4LyYeSAue8hus26guCvzdDsGw7IS\nCqUTK/zmriG0UjPCD72jMAJWkrTc48Be/7cwX+iEg7HsHgfitA8xyTKAGSxq\n9oQBizjUKn57tmp48vVn/b4yWD+nsnJJMWJB5VNijuNnNOlBaQHC5pZDPr8b\nkWBhIjWzSogqNpodOYrfZ4C4B6d+1erUvOGxCwRYHknD5Zf8AWr2vM48b0yQ\n/MBz\r\n=v66+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCSQCPRwD2w/PpD1qVOfojeLVfGu1CmrPGyi2wnb80IxgIgJkiJMOEQl5/HuW2OGOAKldzMTKhaEvfzYnY1ZdOGqfw="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_1.4.1_1542128458044_0.6267727856133458"},"_hasShrinkwrap":false},"2.0.0":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"2.0.0","main":"./lib/index","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"bluebird":"^3.5.1","fast-clone":"^1.5.3","lru-cache":"^4.1.2","sift":"^5.1.0"},"devDependencies":{"expect.js":"*","gulp":"3.9.1","istanbul":"0.4.1","mocha":"3.4.2","request":"2.67.0","shortid":"^2.2.8","uuid":"^8.2.0"},"gitHead":"1810a60b54629c9ce52f1843573717cd493e5fd2","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@2.0.0","_nodeVersion":"10.19.0","_npmVersion":"6.13.4","dist":{"integrity":"sha512-Ukws2w/fg9R3EeaC9KngdjIeS7aoWd08pH8GGkUSr6BLMYXWHSnok/O3NyIrjYXSHtbCeDtIshEuFEZPO3V+iA==","shasum":"9a23de5416bf2fcdeda417f451c5907bc9da08db","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-2.0.0.tgz","fileCount":9,"unpackedSize":60940,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDr2BCRA9TVsSAnZWagAAIrcQAJTN2OANOKibRLU+DtDz\nosi69J8u1Y14UGIVH3ZnHLM1IqwyY3aH9wx9MIIfWLdcuwTF7Fa2v10kYV8y\nNnaZvub3oDOj0TK9XY/PghtWIuuTL7FdmuY9N/lmX4Fg2EncnHF66giWu6BX\nOGj0oks7FCKTPX7SFhbNpJzldqLxsOBOEsPuJQ3gQwqFhXn0BCg1i9R7qCwk\niy6qs43KFWJqUxXW0WuwF6KpCQu9/0m0REHHro3MWJaSaqw8IOljyxi8J/Z4\nBDRXbZBX1V/JlA+Q+YrzMfgOhFp7YUJpRZgzNPXIdkPAneqYL+sy1tjCaPZr\nMZnkeUFtGHuW1dHV83aJU+kcVeDPP5q1G4Q7eb5GPRAT2+yIYqlqCy389WyW\n+ilV3dBE+7b0O8eXHJUHCP/N2w22UYu1rP2qxjJ6bvFS428owGBlQd0dtM/k\nS6hvYDSaVMt/BMYSgj99j7OWoG21jLZ6F1t/2mL2qMbXlFrAOrqNgIPjXRdt\nzesauo3s2U84cqwuLHm/4SYwq+XNShTnHZgaais5RjcOKZpt2A4VLFkFPsIF\n/0HZxRcWIJ2FbfMFdEGw1wSTci6UNl4+1DJ+DUo9+ByvvpCRXgva3E4f2wbB\ndxUg7723NuqVWfMal6WEZOttCgpwszwkv7csm/FkZmz9vvoOLS5iExV89TG2\nhlRz\r\n=2M8h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLyQBZuYDUT30vSeOKNCc7SbF0YHebf7GiqisWH2Qy2AIgX3wKeEP/cR93b8GBxXu2LtXMg3xn0XO18BDuc0nW4y4="}]},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_2.0.0_1594801537252_0.8195652965308862"},"_hasShrinkwrap":false},"3.0.0":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.0","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.0.0"},"devDependencies":{"happn-commons-test":"^1.0.0"},"gitHead":"eeda8f6df5c9904d21b507e259adcca40154ad54","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-TqqxrXZXHVUI9FTk8oU9DMUGOlYtA6ePm9CyY3Say0w/vJgClR8pnXXvwe0fFaplQXWqC1kW1QqaAymx406A2w==","shasum":"5b4b30770a56b3014ca692975ec4ec428243f8a7","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.0.tgz","fileCount":9,"unpackedSize":63672,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiHn00ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqVsg/9FUp2J6FZ4/d7oMvtr35iZ6CwJaCZmozU8YXCR2zzcTb+7uFm\r\nmok6RYdKz1Y/XcgjMvFzJUkvXuzwK/sE30PRtrcEY3jejHlSx5G6TUbl5Ezv\r\noHInd8v20UNUg1UbzZ+rZKcJjNGWpU0JTLuY88ozv2VcoNcD1IFbZV+XpRIH\r\n2c2v/DTJ2xyOjQVtiF6Av9YjOXr07Cen7PdhJM2Bqzti/zyOq65XoYtOktSL\r\nfvEQTLDIbbQQGYGE6JMTQGqRLFXeIkxKcOrsMZl69rxdpg43YkgAXeZhmtf/\r\nX44Y+wt7IpMtLdWv2WVqt+BqfoJqtCkhQOsxl2BBfwCRyDcSkV3VckB47jii\r\nRxmhWyLsB3vuzWkHEzn/vjkk5fb2pHDNDjOl6t33zuD7RCX/lSFuGxS57Cco\r\n+JAIqNzE5Tr9/dpg+RhnnbPnWH3r6pyNFHtmFrWeCOXTdde6wlLuBmc/foOP\r\nOWAJ68tOEoOFWhQIX/6Pbv9YGQ8I17f3WuC1kDfeWgk0Z0rr5/CynFWiu+AW\r\nuoXt1B1k9K8vDnFA5lqDxsBfnExUBktPDUVzvH6zmDRFdKkTKWQvl6CEX98X\r\n+4uRFfEs9CLOg1fJ1amJ5GxxjtskbiWYhNkWuw2Nryxq3mSOuKK38R1Z183Z\r\niljjRcLnjSAHQhIkQwLBWAytYYzjyf7S+RQ=\r\n=fCTG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCR3IvezDz6ai4UBNxojQK0ruxJZ5FDSC11waOkOuWvewIhAL9Z2CX10BBANcFbembeGEGpekGWES9rKOVnL09wX6+J"}]},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.0_1646165299923_0.8776592704096595"},"_hasShrinkwrap":false},"3.0.1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.1","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.0.0"},"devDependencies":{"happn-commons-test":"^1.0.0"},"gitHead":"5c630df63ffd761e64c5fd005b044d84808d916c","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.1","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-CJbijIi6dkLRYUXs7FH1oZSZnb0n1AR+NBMDLlngLPCTe1zo/JhSv4zYO4xDnKctdsFcDfg8MqLkJK6gnyfspw==","shasum":"abf933724700a7f082128934387e1aec1a5ff541","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.1.tgz","fileCount":4,"unpackedSize":25693,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiIL66ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrsdg//d7x9e7mCkaxKcyipOK4WfQ/8CByOGSqqnjmuAiABsdPhbQLw\r\nmPNeLZ14+LDpG3ZEMKYYHgGb8JnJB5LC66bWjruqvvFzArCdBjmUYdR9mlQ6\r\naP7mtK3Ct6/p3uxKwrfodhOZ7KheQ2EHzjzLmcA3jTCjOVgGV5sCbg6OMUXH\r\nc/MwbKCCgq359849hLYu1qnSwZLRV2wH7zYhyuEui7kS936NGOSLOwUxpaO7\r\n+SO9oNv8+u0G3Ao1kK9GTj4H/+CNuep/wjR042MFg0/qiqJk2J5wzvB2Dk1D\r\nV+ndvhofxmKMyMJLBESNMPnVUKdVILOXnw4/x82RwEHMdPEJGmsDjyon5hK3\r\n1xM8096I73gJDp6RAYoBAU1Qs6MOFjAW4TB2fQSVpkx31SmQWXFYYRQgOsjB\r\nIDhXQ3qKK8sRm8iDl8NSsXjgwjpa/DUsfljRK4+qrR3z8h3rAUheoizEjudZ\r\nkf2DFztk5yVeXihtRAMBwxXVhunDdrwS3f11yujsAn3ZWBWBMhiA5sH9oUTu\r\nOoMhDBYcVZNhEpEVq85IOVkWQfSosoRJ7iSzCflXQ4ZkZHxFbvjZREcgFTAz\r\nbhZHmnY6bf4gT22LAcxd0jmiJZgHmrum8w4UP12ncFEE05FQzc6c7cACSjAh\r\nD5bI2RM9HRosYlGyrO+8S4Ty4UHiBfjNco8=\r\n=uYaB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF3xtHNOBdMJkLNbiw/d1BW4V0fVPWUuiMmiHBVTdFIdAiEAg4q27Nk3fPe/kHyhmXommUjDCqdJtze0Btz2qGf+qgk="}]},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.1_1646313146507_0.8605543700446052"},"_hasShrinkwrap":false},"3.0.2":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.2","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.0.1"},"devDependencies":{"happn-commons-test":"^1.0.2"},"gitHead":"c207a480014df818acf5bdd44f931f1382fca8f3","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.2","_nodeVersion":"17.1.0","_npmVersion":"8.1.4","dist":{"integrity":"sha512-6MbrIJRgEpDuqykfXFx1b8NMFYhpUqd+5lAhkTPv+CC27DfdUM+D86v1q6TZFakKMLC5YMftR9WBoZIToHQ4sA==","shasum":"6f1b743e5f8aecce3c1dca646bbfaecdc4bf3498","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.2.tgz","fileCount":4,"unpackedSize":25693,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiKzO5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoxqw/+J+KP9JJ8B/h8Gwb1412kmvRR6l4EE/bTxyH6Rcz9AkMgriKk\r\nwR6z4ReqBLSPycO9lxSyYfjc27WPqRakC+BMMv6+0sOsP95mYRCsxwQ/weM4\r\nUf4yiidynt+qZ5utRVTYxgYZL+EGixxo+jKA280SqzSy9GOB2spZDAnfRjll\r\nAlcoQARNG40t48dNt1sKwqOLc2AqESRO+qSNYKZypsH55CMJXID/TdVBNgLE\r\nUF0n/xkmvAQhiAoG8aLqhuiCtFTwrArfn8T2wRMp6nQTmtQTpj3ZQ5x4Qk1a\r\nrkqVLG1xVOeLWCHaq+rUQlJ2Est1iQVp1/QHY2mZr3tVhJnIWkHrfmrPdHNf\r\nMDtKzOQgn8vlRLcxjZcFPMwF0HrVfYVRsWUZV88Eq5/0XFORDgzxnjjIix11\r\nyea+LlhGaRXU3ZfJJ5PJcKwzbxNFe1UGtiNi87/MrDzVhfoVXpP7LOUWyQd/\r\nexM8QEXRsM5cOCCFocd1VKxwslbNspBo/FYHrU62TEAtck7J0GOAr9N5Rl0H\r\nHvFw9YaZTqmliuO3C9UxqXP5XSIYOFxVB+5CGn3cERt56jXYA3HfdgPbU5iP\r\nQsmzBXeYw2+sYZz/HhthopfAztviWoBVgWtsD2vUhhWM+Nf9CiFF/hLnQi59\r\nKYfQcCWhDLeGW4o4b/CTwrjE2JLc0PeXOaA=\r\n=dzzV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICjwH0SAGSZRJtfYdZIthQo0nP0alUBVA5Ej20eQbbrvAiEApxNXaLHOFFVEqxIINiY5N7mhw8YZ+63prb5ovGvDHSU="}]},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.2_1646998457069_0.15525174350187543"},"_hasShrinkwrap":false},"3.0.3":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.3","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.0.2"},"devDependencies":{"happn-commons-test":"^1.0.3"},"gitHead":"3997c08f5f2630e6e099b8496e2620083b3d5eb8","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.3","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-l/TAkZI36ukTAQi1/f+hmDBVtMgP7V6WMZVcwTDOapDmNgJx5J6P/vaM3atiCCtOsPjtgduptZRvPdre3cM3PA==","shasum":"3d7cbec6bccff57e10521b94cff903bdd7d7df34","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.3.tgz","fileCount":4,"unpackedSize":25693,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiQ/33ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmof6Q//TvcsRq6las4sjhE+1ngvyyOXSfXQPKvUai7grZ/wMHjX7hQS\r\nk19Dz07ie2NfbV/O0vaTWq67Ojz33CTSnN63NcTQ0dv4ejmsEKnLAxkQmjrr\r\nLJ3tNsxS9LTwhtMXSGHeZ4A/uZbyzWm+oFU8jizKqPN9F7M7nBDc7LQc40Zu\r\nsrao2Z+3pJojhYHE528bZDj7+3C/rBOU0XATMQ4dwTRUuExJHUAAYl+7rWcT\r\nZ4bXDLm+y+iBlKu1HLSRMCoA5kC9w1v5RQNvJK6n6S5g9PrsHYlZeaohfGKz\r\nlAggcn7KwCpQ6K55akGIMB25Kkr8f8S0fYztlGkrX/ksX9lpRQlRvb/55q7X\r\n3calWBGmcdkPb36JFSIYRS7Hzmw7+ZGW3KiCbPrzyDl3DY+uRoA35j4XB7Fu\r\nnNUIdErhO1oPMWdvJrohe4oQPIN2MDGmjnqzJGEu28c+mA3U+VJg54oQHQST\r\ny6d9cj4CA0bd1EW/8JrbdGXdiyljgii3sihGiPQ9WSTejkDde9Y5eDexLSN7\r\niSOLKQTdFFTqIqUsLPEE7Wy3WyKnf9s9fD+QjtzvU2Ah1yxIec98dbCLvuCL\r\nz3GMlbZN15DoWz4qYjvZHMqV6QkQgtOKL3GULVAOVyjoYdz6LxLfqanqQG2i\r\nyt8WLZGueYxkTqz/iD/wt4pTpnkvHG1zRVs=\r\n=QhTo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICU7Qrl5zzNoxZEpKFDSEwP9j13w5WIOB7vSnbYxZ6sSAiEA7Lyw3kc8G642rTqM/Ca1yAUOV59uGEF4l1z+Uy3o+GU="}]},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.3_1648623095573_0.5282697459618941"},"_hasShrinkwrap":false},"3.0.4-prerelease.1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.4-prerelease.1","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.0.3-prerelease.1"},"devDependencies":{"happn-commons-test":"^1.0.4-prerelease.1"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"90268b6ca2497cf87638d323d872e74e1d442051","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.4-prerelease.1","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-lg3McjHi80vUUitlyJS7FxTLXFi7/Dux6LDUGnWV4u2uPpCvjUtIEL8QVvk1i1BfUKfOEB5nRzl1yRYJWUQlbw==","shasum":"a2fdf7083b75b6f34c80e30931eef6e8c30e9dd0","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.4-prerelease.1.tgz","fileCount":4,"unpackedSize":25732,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDuHck1AZ4lRgE5pKoZG82bUExvRl31y1V2kkAp1uJKzwIgb1KVjtJRc5IBQfjQDmJT3SqsIsjwpExhde7gCJykoqw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJig7iiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqtug//WCG4QFuXpNWs5JVgst11+0etxuVdYqnlDUqqFv54LsiGTGDn\r\njWR1KDjJmB7NRblBNnZpdmUYd4uUzA8L1u0G3ytO8f48OdnXhYeXl4KvB7hY\r\n5tb3nbz7mpeWeQFQcRWDkJFbmci0SkXfWLXFjo64yhaUrMgCZDhX+rAvF3fJ\r\nr5RJNH94M6UP0cuhK3illFyEicPU6CSuc3XEDmQ1t25QerRx7mi/tq6dnTj6\r\nI2+MwxDzoWKXMK6stgux3xWn10bO1fGH+LvENepO+3/3wx6X1u5VdzARHzvg\r\nnjtS5TfFkG5qeMlQCTkzh60aEcv4AO0ig+EcA/d7Pj/9BBqKtVL04DYtoC0x\r\nBYUKyLxqi1BWAae2Ieb7wFGnpZ3+W4n4GzPuqhBhnk9qitmlnuy4X2ziOV+C\r\nPvyp2ubL2tqADX8+iPS1kwNpyVKJCiv5EG2kdYZCDnYq+Auy54Y6xpE18R96\r\nZ/4Xdsqw9u8/Fal6IlZhdj68/PuJZ5B81RWIPgKyduIhTwyT+TMc9ePKfPke\r\npzN5l8nLGOl70y6cZ2Z4uEuy/rnH5lbPsuE9IlE7MVftuHLQXc8yarSEwOXC\r\nx6C01nK8LhGJ47HJQLv7ZZ0kmxcETEPbTk9ll1qior790QHvV8IY4Wl+5DWp\r\nIll52xoazk0nmtEc6c4su4Rm+EdOAR2NusE=\r\n=PjuL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.4-prerelease.1_1652799649949_0.3584290148296494"},"_hasShrinkwrap":false},"3.0.4":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.4","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.1.0"},"devDependencies":{"happn-commons-test":"^1.0.4"},"gitHead":"9edbe27da81b88a20053d108053c413c570e545b","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.4","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-cs7bT4GFjzRhvOTtAAVOuozviEm4wXIq8lX1yYr7nFzyJ0ocmM0UmxHcODlJaiEJGbuCfKgPBusKiwDJpEaVKQ==","shasum":"b2cd2fab028f1843d120f3e51afb7c3d6bf8971c","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.4.tgz","fileCount":4,"unpackedSize":25693,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDuWCjgXznsa2CbM3qL7w9q/6y0DfVGtJ+yuek4JE7mRgIhAMBQrhLguzi6bkI1weWMG7kCVaoCY8m6QaiXyffH0s0/"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJikPZnACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoQsw/7BU3Pt6YRaCwJaQI/WVBmmR4GAx82bWM4ZuUdbFLzLPfewp5C\r\nSt/N1ycYTpJtnlTU0PnwKapuoSuuUS7IEZWsBIQkuRDcaYISuXNokDAcjhWF\r\nRT5D8Rao8d2yhbnflzpGxBrZItB4dZ6L2y36ANwIQhjrOQPvJ/zKmllyhubI\r\n/zRFjQy+KBc6wxloioPUN3qyJIm2bwd8F/1ysVnL1d7dnEfW1O1znlnG1rl9\r\nSLfaRGKjBYgDigELWqlDDsL2ocCfLMr28naTNNbzmwdSb46hqEpvsq5MMd0C\r\nE0bt2ohTiMmJOibKUW6EngS+SJ2IlULIGP4dZMo7MZb26QCZIYjpWf7YIX9G\r\nE1rJVX7LZIc6SIW7H60v0di6JZSgMG5bBjZK5DRw/xQgV1ATCRjaHnqVb7l0\r\nPfe164xLAmhXZVJmx6FRQ7ia2dcENQ6elZ5K7bvdqFhDAmP6jGnqfgcfCe1m\r\nnYHWTKKq+49eG0V/Z2lflAAwoRMpHloEfX24oLpaIdygtk20q3OHpBz/i36z\r\nWV0CJEIHzMCukO4DTQV+G4eqe1LluK5lMNR1dxcAaaMlT4b6LNTDcSNH5MJM\r\nVxykk6nKmn0oEht+QzimDBnglPUwZscsXl+m8wYYdmRWEss8GvFKsXg3+dB2\r\n+NIX9eOswvSxCpS9EUxRp0i7SgXuqcUhMpE=\r\n=Pjo+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.4_1653667431482_0.8457029389410318"},"_hasShrinkwrap":false},"3.0.5-prerelease-1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.5-prerelease-1","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.1.0"},"devDependencies":{"happn-commons-test":"^1.1.0-prerelease-1"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"e7dce20cd6a8eaf7c6efe07b28d5fc063775288d","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.5-prerelease-1","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-fHSshlj56Y+JC9nSd19cYAl7O1lKkajyKto8jw+XsZttteDthUVDZnvbFcKk1f/22VYzlrnQvQZTvhuPxlCZ0Q==","shasum":"47b764d5c1b81ec61c7a625ec5138f7e7de2180d","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.5-prerelease-1.tgz","fileCount":4,"unpackedSize":25719,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFcJCnaftQfCVuzUIWlAfJGOeOfFpqxZxbSUzOXylRV/AiEAklFJ+q6acYxBiORUaW93+oaWauDoSLYwjNdY6ugz1UM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi0APxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpOwRAAkd5YueLrG0PliVsKX0vqhg2dM1rODU0pVNyo5Lzki0ntOPcB\r\n3fh2I93t8cgSKPVBJ4BNcUHrHU4xso2Lbcvo8JtDKSzE+0H7TYPn7yojg756\r\no62tMJN2c4GAByH9s3VQ5mTOQsAbmLvNOJxHMiiEDy3eymB5g5MnQRf28/P5\r\nYj9KId/kLrPa/NAioqHW5UGHwOLiwt6Eb3LygVwISf/fCaDIvtbw1+1Rhnh6\r\nCSuBOSPhqkA1/fKYsvKyKHJkzFJszK0E+h5Wwc6nOK/UO4hoEWn8iuWGfAHk\r\n8rpj9srO1WSfj12S4w9QM3I/ZtdhX7p6riRJ2CK4l2OdwCW1SnbNMegGoZvu\r\nOQZQRkAhq5t/IQbAeOZcFOkwfcrsXOjqBFe1OU6zWiP84HNZ3z08Hchkkqa/\r\nh8aG8jEi+aVELi0UNsBSdH9OcKVAPfGrC7TkMiyWuHyIhdlgjJC7IuavfmGB\r\nVu+Nio/N4L45AWOuOqsVlhJvjDfHzylfiYpdSPuXifqfAtr0K70bzIo7a9+0\r\nz2mwkljmgoD9YAF/6+aeuG2Y5n2OtgJ3SXFAAwjcQzsJDyUqkL+OS0BMH8f4\r\n33r5RZwePKSHrocWIS444CCz+9tw8v59fAD9GicX3PEfzu1w/QybRqpDJQ34\r\nBmZ5O3mc8qo2hK8N8MiHqYSvVj3E9slMkbA=\r\n=NVS3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.5-prerelease-1_1657799665052_0.15894980170938244"},"_hasShrinkwrap":false},"3.0.5-prerelease-2":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.5-prerelease-2","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.1.0"},"devDependencies":{"happn-commons-test":"^1.1.0-prerelease-2"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"fc3961fb73d4c2caaa5dddcde713073e377b665a","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.5-prerelease-2","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-pS+j8hD2Y/3McVn92Bk21Ppb069ZcifpgyjpDb5PI+8fmw+Em/bFEBBXRAlyQtt32H56F9d92Zu8Y6uGP890fw==","shasum":"7991ebbc4978f6b49c4312f1cac405dce2d013dd","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.5-prerelease-2.tgz","fileCount":4,"unpackedSize":25719,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYcWGjhqH4KBaBvhvif+3B83VQuHiUC71w7nKeV0ovPAIhAPIfaEe+w4TpRWis0ppVvIaK2WwAt12QoiBGIXVA7VBB"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi0B5kACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoKohAAgMRU+6hVuJs82NkmSyUwC0nH0/118Ltwv88LfaGfqaI9iLBX\r\nJsZjJPka4+FUJ2kpEZDoI6jR5E6hFg9/ax03tMN44Q7Wz9Y6fwyv/kXN+Wlb\r\nXmHmDtD145GjPWCvVchlUMn/LjR2FNXcI+0jVTGuo3K/CDNyDXzjIBbgDfDV\r\nz9AR0wTU0vp41VwuKB3fzMjdegORWEoopqxcAsH+dY0N0Z8tgSsesoC+JJIH\r\nLHjI2o5PK8gJQDSBmy4JWc7oLkCLFc4EIKxIYuchss15rLwGW7nlynR8S9oh\r\naJIqF8G2mZG0BU+XPs6+2XxzFwCEMU3m0K+qRtXrGtvw3MeMkELgdhUd+ZL+\r\n3e7oP0VAQrqXWVJ7/TJcjgdkzSm2A8JtYLeswYMM6iEugNZp9q+IrE/+kSrn\r\nHebPPVbNKTVra5h+LgHEA+6KVAi0QoTH8gRtxyw5V3L/d6uuToYNrwMoL/Gt\r\nl+qqVMulOvqF3RZY/aG9dMgcWeYnTKhYtF1YI9Cg+YUKBjlAZ1rWDBbcbm/N\r\nprNULXUdQc5OagmE6NSSawgBTBNtITjARXq8y/k58Gpf4xPNgBegshgv206u\r\ngRfeSrczJ8was1/ZrgiT8S5q/1Xe6c0Y0bGWAQR/V8cZsem/KYzE8FdoFTst\r\nxpJO7L3X7SkUm/ZYEafIVwFGMpnUJePQ8qo=\r\n=E9Ce\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.5-prerelease-2_1657806436072_0.2522574948746239"},"_hasShrinkwrap":false},"3.0.5":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.5","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"^1.1.0"},"devDependencies":{"happn-commons-test":"^1.1.0"},"gitHead":"62047eaa0a0e687561a12e041ba27f2eef3a5123","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.5","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-8Yn9CaGHlkh0bv0Srrn2No5/SaFyJxiqO2pD2FwSttwsSxbsbm/tAyDwMAdUn3Mhd5hIoG7wr2HTGAcSikTC8A==","shasum":"bfb38b74bf09a14db3fe327baadc0e218145c2e0","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.5.tgz","fileCount":4,"unpackedSize":25693,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGW6P6aGxeg6rodkIiMWFWt6ewZqwxOPU8cFEOJHriRvAiAxtGdCyOpbNiksPWzaTGPl9Qu+EBKkI1kpvZs9ji1PYQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2QhcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoqHg/+KmHcn4Nf5xdPQP7hA47+ESATqznEE+NXgmjjDptjuRMb9gZx\r\nV6nBpBTBijcRPHeFTRLjwtkOIPaviCHOoCrSnNO4+BOLA3aSb7ZniZWO06aG\r\nvE6HPgMlYpb/oknDz1Xi6eWQQiqf/eNPZBD2xz6ygSkJcvpGsyUdkdQHQuue\r\nGc17D8rg53v1njF9nPEIOc8CkFiFWKfCJG6AZe9JCRnmT2WFTYC8sAtVJbu1\r\nx8betCsSf89mZxcz/sr8G6o2BlGDMPNq/Pfw2h39kExHRyB7AydHj2uqUg99\r\nE10187dkrASl8HtZSQ1rRzwcfseThFYf7Wv27sdXNhqEign5XBEY8aja+FaW\r\n/sCmlkmh1ZaO7Un+vo6Yzs6N5duxrnG1uXFa9Lisg3EvihoW3yZ04IAy9c3Y\r\nNwkLxKu3zEKJE186mSGNZZZ88KCDG9RfXTFlgwLvRgnGCEbL04xo95O9TJ0e\r\nMAsBOO8XULdJht5LinkjLU5ZT8ah6cBO8nIRvRqjYMNjZStdpdvgfmHmtpex\r\nneSz39rYLgqZEzpwtnVBFh8ilh1mIgvtRIO78PubJZB2Yp6cTj1ovhC4SEuU\r\nWVq8KCNFtc1A3H24IMWldzhDhmprzXRqrFJ1ovWo3/1Bt5ZVQ5SHWpjs3+HC\r\nqpkTgi49DP14lUZStUcoc9plBShVs4N1J6U=\r\n=16ca\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.5_1658390620620_0.4801787978145131"},"_hasShrinkwrap":false},"3.0.6":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.6","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.2.0"},"devDependencies":{"happn-commons-test":"1.1.1"},"gitHead":"c4297a23b1837ca4a5a9aebf9c4cee0c47bea12a","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.6","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-LJDUaGFgx6owEcGNi7fVUASXgRaWf9XWuBiT6haAu97eincEeqm7TgB2lT+YkKr2X5vSPF7dxBGo+uW3e2Lmow==","shasum":"e866dd1d04048e931667cf9cd68c3544adbbbd28","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.6.tgz","fileCount":4,"unpackedSize":25691,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCrPwKgKhRDELBC/c2g6iP3i/aHLQ0gpbkoll7QcbOMPwIgdcVo4ovSy5bhpA2/q/RZBRO2fZrtwbmsb6/pINvkDvs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjYSXhACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo9Yw/+I/p15HfPgLXhPS3Dmfj147T/mQUBF0xw/rUvinVKKD2Nax8z\r\nIHPeuf1O+cWQYZ7prP9BWtGQqjrEMvcRxu8HIE/QJpVzHVAOgxay5GPE6TfH\r\ntNitaTSykHXaN//aV+U+l/iLTtmZSZvWGOSxXgmMTj8LYPyyocJRAEKrKW5A\r\nE1uNpwjZCTlVAQz1s0edOugzZgPaLhlprn22Czod2Ln2dhU7Ggbl8vXUMJYZ\r\n3jWxUmrE/I3OLeOIiAtSNpS2TQNfo1Looo33PZZRPTIS+0YF8LgzgDWr11rp\r\n+M/LoTAYNEgr8No0pxNljEFXADTd3N1WqPxbvP6DK/+X/fAUE0paaeCVcTb4\r\nePGRNUZcMVxVkhEUH60RjDR/3/WO7tXYA8WPw1ouogQYVrAUlOMROdfdui12\r\nkmbTBI5gdi4Vfo2ppUjp4FJZ5Kgp858apMTOcfp5k6Y52Dbotf3ma3+CbNaz\r\nRY0jaNysHmGR+LSByYQehi2fxOxu5JG4ktXZIz9PmEKX7A15R2X09TrgYRUe\r\nK9OW4qILe6nQIJkvTjo+1dKTvxhV5pHvHKi13ng4+oYpQmIjw/acOtzhJ4VO\r\nKnasBFf/9CjZxZ+fS5y8koNfH5l1gj4eVxH8JvKRXSV/gT/zU//r7FeJNUaV\r\nhSivaEls5nw2qGepcxZU8te1Ux1cc2ip3V8=\r\n=A3Fv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.6_1667311073280_0.25808956027255214"},"_hasShrinkwrap":false},"3.0.7":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.7","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.3.0"},"devDependencies":{"happn-commons-test":"1.1.2"},"gitHead":"39c9cb4d139c6b85245e6fa2a799d5175ed63fa8","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.7","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-DfAlm6RiK9xHE86XHhuJZ5Bf/RAx6ZgY7lqbWrDSMVOkyTIVNmRu0cJG/i44f7+mj7g4i86gvzxFwVpCSuLNbg==","shasum":"fab8c1a26026c3546f4cc7d92327b039cbd83882","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.7.tgz","fileCount":4,"unpackedSize":25691,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDJcD0trYZ7owYXDF1a7dO2lWvOib+nFVnYIB7kBHrT4wIgSOUzQE1WSncpoABZkuyg9ZomJ08t+wjXSuzTzTDvhTA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjgfISACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp04A//Wr/bt0WTTqrGdaDl92L3H3rsuzUWNSFdr6wwcG9tCuGdRprD\r\nx0Wma73ADqaya9Sftz2NYH5cAgF43At+hTaZu4huIG75Ey/aTIOqYjOUlQKv\r\n/i7D40LCMAwQELp0WbefS+K5+blwEiCrHcry5ujPANKkbdcsyuRXaLioCWu0\r\nsu9hL1wMCl63yLAqphJNwwcXURAastNCSLWPmZVKhJW/Z7YE0LwQwbWrJpiT\r\nEophhnvsDohZICu1MNaQub0eKPK78/bXeFSUKqev8IKC5+MxBeTOkIdgLaG2\r\nThQ6Zm4J7ub+Pw9fyxtega9KebJu6f6GDcuS8Y5WYqV481YoV5DJVT+AMwzM\r\nJQs6fqKrK1btMPPOnQMEyvvzEoAYp5Beyb9fJKoRMkkvLW6L+OJzZgtNdUOF\r\nXj7l4E8Fyp6mE5/8GqlMpcEATRkZXsyxZlRKnh5GnnUAAinJ04/QpXHN8icf\r\nLEbjE/ZTgmkp/g8JtGeQHwvkh01PVOeB7bdjN62bCAqlU6XbtNRXXJLdaOtj\r\n1Nun0aggdtGQ2XX1bWp//abxhmsbNcMReiEz+cmvgV+m3tO/z6mPQD3piabK\r\n33eLZp1ge2kURvqa7T613y+otOBM+JL2sU1hqSuGJJRRx+GhY2LiVfn6IA86\r\njQJ4U02EcAP40sC4y+8k0+yj+UEjVAkXs60=\r\n=zr7R\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.7_1669460498387_0.6730516290133488"},"_hasShrinkwrap":false},"3.0.8-prerelease-1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.8-prerelease-1","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.4.0-prerelease-1"},"devDependencies":{"happn-commons-test":"1.2.0-prerelease-1"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"33eebbd4ab176e3e654c6193914665d6840ddd0e","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.8-prerelease-1","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-mEzSoifDpKoZAn8k9d/mZ7/6D02Fv7DfK01d/4XRrUPGHFsLFe4NYH/wOZ9NVpKTe4sWeW6GtT6nksHHuHn8XA==","shasum":"3a093b83b0f881ad3d3235d730547927305ca874","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.8-prerelease-1.tgz","fileCount":4,"unpackedSize":25730,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDa1loM/7CgFw8sIOXo1dqnXceBvvZ89SOclioompjHrgIgcaYGY0lmULp5L3SIbwLn6W9OyWOnQ4hS5ZaXLat8N2s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvu5MACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqhWQ//XuKr5ist0dCGV23xSvxwOxTLawQhs9rLvt/PYjIP6P9Gpzk3\r\nW34ToRxu/eciUQX2yDYdQ4U5RzWQGo//YJ4ZPdb4qrxxjhpmJSBdrdhEPTIY\r\n/BbyxMRegjqfBFl5Ao4OQHq/j59ZBxMxEZfEXmEmJaznfo7myxSGhKmJsl4r\r\niCK7el7sZRbmPHDBgMSYSGjlpzsVocW4SsfSVwPAE0wlq1J7dmctCaYG+r6C\r\nkNkvhlzFOaqc5GvWvANh3LuKAXaMFaViT2tbtqZb7FXs/hlyJFJEPrKgp9LW\r\nz8mCB88Iyijj9WP/ZRj5wD4p0J17DjOyi1r8xA0tl+243TgM+t28pD72fI81\r\nMO7rJOavz97qqQkfcf39dlNnE2TJoJTnHhfVM91PLhS+Gg1Niyofx2Wv5dJM\r\njVWT49rAohtNBacWJeqbl9qB70cI1YQETxL7lsfE6SNefO7PQN8orrk2Wzro\r\ntUeY11BpAONQpRZId63TPn5Vn8l3RxAHKreI7tLWoxf0S53kXn43jIRf2MXG\r\ncD0yFTCYecuqnXQT3+KiDJsj/rekWzS7J1b0QB7UmqnOyWGWlEyT7A381NXK\r\n9Ai4A/Klto069nenemjtoBrGyZioymexIZI5QxI2MtiQ1S2Q295PUrsvlk3Z\r\nmnaBo7nbQOn2SpGtDcYOKB68Uoa+wX3M+Sk=\r\n=VRrh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.8-prerelease-1_1673457228499_0.4234046283183486"},"_hasShrinkwrap":false},"3.0.8":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.8","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.4.0"},"devDependencies":{"happn-commons-test":"1.2.0"},"gitHead":"d3319a3a74d1139c8d9d82123d22d2137512170f","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.8","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-g+e1IAXHQCRfZeuOaHyaAJ88R8GkNzNftS38dmFWZ0imTFkaL8SoHJlPohquSo6fkgLnvBhh1Hz3w1DCDwYrKg==","shasum":"af47f7208734a40a3f2919469ea7b1d5d7b51c32","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.8.tgz","fileCount":4,"unpackedSize":25691,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGoxd/9YDC7e/E/++t6tBqKA1BrBTHQ++BdqddbOkEY0AiEA0zuXwmTVLHe1FdWOTuymdGjLwa0f7lMIgrxS5waQAMk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjx9DLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq75A//VpfzgKJv6mZoGoegcXtq2XtpM3IScf3NOhOVlrwpKLpe28Ul\r\nTaKHxEsIrMa0Uc/1BLJyd5O3V4/NCrWmnHRveCZpLjVMIr06nCxI6rRwoK9J\r\ngTsKqhTZjFAK8scH2URHB44T7y6h9WGjHyACS6rNnBwHYZ93RJqVsVlB/T2I\r\nf/bRedzGi9T2OaIk2bdru7tyFWXqxFctfZvEPgcdgkvqhLlDlE5UixDj5KgE\r\nEZUZSnQ05guNkiJ5MjiLCw+WIpDQr9jHi7yTycuikwvaVlNgQw0SXvIPtqE8\r\nfFOenWmGhr9tBmO4cMaejHw1o2MWP7iUyK3U18tSE+WKDjlrGQlAc0EXHQtL\r\nzhkud47rEH1rH8NsgvIPnkuLya8tLF/ZvNZXobV6FMeoE3rM7A9t0MI9snhz\r\nZBppHVbR8dQQEXM0kAhclxdbiDoTZRdDbr76vdeX7dMVCfCcsnwE64YQTOgC\r\nEbZTPAyoi+/zf4iAXpJmtSU+vTYW0kd5I+rFg6N62dWbouXF3+agXDcUoFxC\r\nbfsfKIib7YGnWr+ozzXI+mkK3MyOLicczhvVF3elK78kI3OWtlNuQoe1Al7k\r\nTlaMr4AWTUIS/oYoIj6UqLCBM95283BzvtAo6Lpo7RDNB1jsQ0RZb9szfvSr\r\nlFLutsnvHj5y1l2cPwRRxjBUnj0Hqb1Gjk8=\r\n=x2dP\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.8_1674039498975_0.9426787144071389"},"_hasShrinkwrap":false},"3.0.9-prerelease-1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.9-prerelease-1","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.5.0-prerelease-1"},"devDependencies":{"happn-commons-test":"1.2.1-prerelease-1"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"70d6413fce09630e45f6d723baa9dc4b3cf792c3","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.9-prerelease-1","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-tiJ71vfK2tnD7tP0UEmHUlX/gvSvd+U0SDv4H5iddkRdhAiSbR+xhtfVy0cy1d/Gu5V1edQxt1JbjKaiWfHo9A==","shasum":"572568f2a4aa5b0324985b9723b08d5bc15cb913","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.9-prerelease-1.tgz","fileCount":4,"unpackedSize":25730,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC03pl3wFllWLh8K4MGMRJPs3Bb+VioYaR9soCZZdGFAAIhAOusPURWoHDDiay8ICwuMFAjDXeNJmfBn4myXJ3jQqzo"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjx/p4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrrMw//Z1+5pUTun8qczL605BNvmOKII8Jq8oNcjD7GXsdADLwwiOyv\r\nkhZEbmCxXyhSKCKBaSKpDafV70hEQ4Ert/B19LCfnscOB8c7TFEUY0DjmwLK\r\nkzL8jlbtZDTyWpi9nGp735iPklsoBzhESv6opMs1o3CSDlzeYXYi21cY49m+\r\n6gjTCEOkvH3ZDAMgGUszTUIy2dRu2Itb1mNjs7AvrlUAmTTbYIZgjIW4F+5N\r\ndDs0SKLkEL+uhVb9Y44H4kxW2tHMU+3BvPe5FZNFwuZkR9uzyeJAxbpOkkzO\r\n+5QRkUuVREScSAWq4bsuQgxx8eUyIUeDGF7Uug0Lnohh3PeS2IKYbezSMycd\r\nSgFOUHZ1WPOKvfh5/So4phDp6fb1VJi+ZjUumrs2MNKJVE5ev/aj0YUwn4xt\r\nvPCPbKyj18OgABe4X737eEw3ZfWNyCuw6JorjW8ebMKAS8yeIGl4MOlBfv8J\r\nuWqlOSFXJQ+UG3diyFouGSU9GjdXFXJJ0Z9oS8xDmsOu8yCrRsRbLaFMcM1D\r\naymGAaT875r/i+B2kv007gGdeVp7yPy0qvLjLz6+UyBpotYeAgYMurjWmicj\r\nJk4NP8YbD1nm2ECf/8gk9ziSzXd0NUKPOfLMB1C3eXLTqlos7D/DxK+Jb/Y+\r\nM5WrC4DbRuQcLH1Hu71uXRra4nXhHVj0luE=\r\n=ee8d\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.9-prerelease-1_1674050167987_0.6563406773441611"},"_hasShrinkwrap":false},"3.0.9-prerelease-2":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.9-prerelease-2","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.5.0-prerelease-2"},"devDependencies":{"happn-commons-test":"1.2.1-prerelease-2"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"3376f07492663de04b0ff6eb77767a59315ff731","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.9-prerelease-2","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-rPsQ17fvWH03gf2BNORSiG5ZbnaIUHK8uQuCy9k5d+BzC3PzlG1N+aiChXno2oqtPTkO9EerqgKZI7zaMVG4kA==","shasum":"f87c34534496987ac1c53292dc1bd894c48682b5","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.9-prerelease-2.tgz","fileCount":4,"unpackedSize":25730,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHGOqYDvW3su/fvpc4ykrgz4bUOuDDoyiseCf4Iak4bsAiEAxnqtOMyY/wip0Hp2GuZF21tpbJIYOuEbwwDFhYCrVG4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj0lg8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq/+w//foNZI0JXVrF9Jy85U/sCMv20axCL0S0rR6P1PSoGD7lhiyUa\r\n2iiv6pp/I6x6NyGRBPJPhL92PshcEbYz0HqA3noUWw/XEdjo53NkAXKu43tu\r\nETRiqoBNw+C2h1QVyyBjQdWhe1BY5IWsSDWt2vKeN4PfBMuVcr70Uqo1lkdl\r\n0hL+HHGcHQ2fPzioPqt5ybtfEuWzg5GlSBV2ScrbJmNUrZDZhBzaIkLQyjgh\r\nCPgcPW4UsvQWVEg4LFraAUVTbyVXpctvfGXoPW6gQd5PJNvZisRw4DCwLHF2\r\nKMIKL+z++wjGhRfn2PCiL6Ctw9eJkmoaydqL7qxzy2OITN7ASYI9QLfa+jMU\r\nPo1jGYuN3/Y6UqzqjfcskdqYaQQbm6EszsLatIlbn3LeptaaELoeQCJEfDIw\r\np9fgkS5kqnA90a/XaPsocs1u67FeWPFXggz3ZVLWR/nV7ZmMfUF3qIPC5AZ2\r\ntKZfBz9aIaLMoaC4JZBUmDxCfGpL4HwY5LIYtz7dhn++3LpGs/XRkczEVpaC\r\nbcm69P/eTaqxPqEQXfp+EHZR3Dx1qj5UrA+7YYNRi1utw4Lhs/lKSVpa9I9P\r\nDGUUQIW9PRiKO/zWMLwxslFDS4b/4iAuAR/ZFJzyT1nCPQS+2MmXv+wirIP3\r\ncUS2sASNs1Z72ge4iKyaukAPGFqgRc8qo1I=\r\n=yXiP\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.9-prerelease-2_1674729532785_0.44975760152928457"},"_hasShrinkwrap":false},"3.0.9":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.9","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.5.0"},"devDependencies":{"happn-commons-test":"1.2.1"},"gitHead":"bde6ce85069d10190abd6f72811a2d454b54177b","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.9","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-VE9hjtXW08EwgeY1B7iqeZSSXrIHRNGLGiyVk9bsDGufl0uzWsmAbKSID4ibxAkciYwhIoU78NkYNkzk/Xv1PQ==","shasum":"270315cc2f2c6f74c66910fa25375e07901df10c","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.9.tgz","fileCount":4,"unpackedSize":25691,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDDse3AFPoJYlkHrIFD7AMI6W+89J7gqIBNnc+mZucNkwIhAMBOqpeKXjZb0m96t6r4v0sAwoWsZUPoFE0CP0+EkieF"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj4OmrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpzDw//UYeilqCljLt8nnjPhslMaAjsWSaFmFVYTQklPnB720ImMJ9v\r\n06QH0KRMzyqsv9lPiQCnfNEiP7zprluhYdxOH0kVAO3ULJvxs2lUKqaqlyHT\r\nzvSXS6QZF9UDxaKBz072Im8iqpjYIFozkOomzelgZDT6wXsfNsHuABDNhpjV\r\nG2/y23LMDcF0yFg63NP+YIzaiMPVLaeVrZxLniIz7mATGI6cFw5BnfEjFtpa\r\nHi4keipHlXm9RV04ln/VOCZIJUFmGhYSqC5YxVYoElMhguVPVyU5fE4JuOBE\r\nZhKByHX0O2U/drDXgPFSj5nVoWp04eyEaY4FLeDyw8qDofX4KUVPRTBVMJnq\r\n4B2UHi4n1O7zMyXUTSTzp3IxL4Qvv/c3TCkwp3pKe9PJQKJztRZMZtk8SkGh\r\njjf1pcFCfhhH6X14bsUSCCbWa0Bv3K3/pbo/WTnTByw80GqJyOB31nXl3ucI\r\n3SsQ0gpGVYvrplEuDtBAG1uuCJgk5Lm/Exl9jUvVmhlT9Q74EWFjzicY1V5h\r\nE9Bxc+dObnNbWXMQz8cQNx1JAbwUHDXhJiPbJIYQ5gCuznSlHBPTelpDeVIN\r\nEVzJ6StEV5wP7uSRKrZi42NHPOEoE0xkKwTC6KPHLIDxf8/d5K3BplDeIeoo\r\nYG/vq3sQVu+hW25q3Y3xqIdSZeLdEdZGIUE=\r\n=Q9H/\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.9_1675684267218_0.7878786631001615"},"_hasShrinkwrap":false},"3.0.10":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.10","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.5.1"},"devDependencies":{"happn-commons-test":"1.2.2"},"gitHead":"a0532d747423553659af1f503ff00fedfeced472","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.10","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-HD95EZ7+n4HaBX4wGnlfg1p5aOk+Ef3fnmwBaVyTfWJUAgX6vezh3GG3VCw5sn5WAQHC9rg8xa4LpzlW8Rbzfw==","shasum":"22fa9eceaab5c89f1a3a988e008e2e4f9a9d4fda","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.10.tgz","fileCount":4,"unpackedSize":25692,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCaQz/mmoDGqYYMwhh2+a3251TQQD0CIrzS9bz6zSKsUwIhALivmUZRg6R8rHNsMeGK0jrJD5NhgNr1gSrWUJ++kt/E"}]},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.10_1691322617014_0.47990627339086767"},"_hasShrinkwrap":false},"3.0.11-prerelease-1":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.11-prerelease-1","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.5.2"},"devDependencies":{"happn-commons-test":"1.2.3-prerelease-1"},"readmeFilename":"README.md","gitHead":"1f882938bae73c0cbd943ef5add26539ad40c713","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.11-prerelease-1","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-zfoYiFa33TJA0z4w9lRhLJFFygY/q+jDM8lUtgt4vvyjMV34taipFPjqUbSd5ZwwSGGNhVZIi0B04UXvnJbo1g==","shasum":"685210b5a7c55b601ac14cee706d03e5cd9ea3c5","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.11-prerelease-1.tgz","fileCount":4,"unpackedSize":25718,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICIhw1RARzNM5woOyOp0kECUERud2NkkBSLi81UzQS3LAiEAxmZWj6T8U96/SdzrZ3/2+DbUbwJlS9TNXmxgf5AwHrk="}]},"_npmUser":{"name":"jancoy","email":"janco@tenacious.digital"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"jancoy","email":"janco@tenacious.digital"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.11-prerelease-1_1694686347943_0.3040527434069049"},"_hasShrinkwrap":false},"3.0.11-prerelease-2":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.11-prerelease-2","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.5.1"},"devDependencies":{"happn-commons-test":"1.2.3-prerelease-1"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"9cbfde6ba664b4398cea3e52ee0dc1fe5fc91a63","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.11-prerelease-2","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-5/6ewse8DKtzpLfpbjhjPirKw7Hu0rIWzfHB4TBrJnftuAT2FvJwBhITyO4PkUN4YXuNXluQwkxRE2t2j+wDZQ==","shasum":"6914ed29d2a5b2965d9ffac7cc14ee5a0ac5abdf","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.11-prerelease-2.tgz","fileCount":4,"unpackedSize":25718,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICgwaxobvGGeXXkXqZg+nBhczc84in9T5KHLW1MnRTCqAiEAtyQAxjL79skVJFgGlV3hDqglYXwSr3o+h15v4W/kiaM="}]},"_npmUser":{"name":"erasmusjw","email":"Erasmusjw@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"erasmusjw","email":"Erasmusjw@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.11-prerelease-2_1696578200962_0.05709150148195574"},"_hasShrinkwrap":false},"3.0.11-prerelease-3":{"name":"tame-search","description":"strict wildcard indexing and searching","version":"3.0.11-prerelease-3","scripts":{"test":"mocha test/integration test/unit","test-perf":"mocha test/performance","test-release":"rm -rf node_modules && rm -f package-lock.json && npm install && npm test"},"author":{"name":"Tenacious and NSOFT"},"license":"MIT","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"dependencies":{"happn-commons":"1.6.0-prerelease-2"},"devDependencies":{"happn-commons-test":"1.2.3-prerelease-3"},"readmeFilename":"README.md","readme":"tame-search\n-----------\n\npremise\n-------\n\nkey/value in-memory pub/sub store that allows for a strict wildcard scheme. useful for a searchable subscription store for a pub/sub system. Essentially the system stores wildcard subscriptions, and is able to match them to incoming queries,\n\ninstallation\n------------\n\n```bash\n    npm i tame-search --save\n```\n\nexample\n-------\n\n```javascript\n\n    var opts = {\n      searchCache:1000, //size of LRU cache used to store search results, default 5000\n      permutationCache:1000 //size of LRU cache to store path permutations, default 5000\n    };\n\n    var tameSearch = require('tame-search').create(opts); //opts are optional\n\n    //add a subscription for a specific subscriber key\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 0'});\n    tameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 'my reference id: 1'});\n    tameSearch.subscribe('test-subscriber', '/test/1/*', {ref: 'my reference id: 2'});\n\n    var results = tameSearch.search('/test/1/2');\n    /*\n    results:\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    NB: the subscriberKey field is used by the system - and is a special field which cannot be part of the subscription data - it will be overwritten\n    */\n\n    results = tameSearch.search('/test/1/2', {filter:{ref: 'my reference id: 2'}});//mongo style filter\n\n    //results:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*', {filter:{ref: 'my reference id: 2'}});//unsubscribes subscription with ref 'my reference id: 2'\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 0', subscriberKey: 'test-subscriber' },\n      {ref: 'my reference id: 1', subscriberKey: 'test-subscriber' }\n    ]\n    */\n\n    //or\n\n    tameSearch.unsubscribe('test-subscriber', '/test/*/*'); //unsubscribes all '/test/*/*' subscriptions\n\n    results = tameSearch.search('/test/1/2');\n\n    //results now:\n    /*\n    [\n      {ref: 'my reference id: 2', subscriberKey: 'test-subscriber' }\n    ]\n    */\n```\n\nextra subscribe options\n--------------------\n\n__subscribe to any topic__\n*it is possible to subscribe to any topic, using the subscribeAny method*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\n\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\n\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   {ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } //NB: notes how this is included with all search results\n// ]\n\n//to remove an any subscribe you can use the unsubscribeAny method:\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   {ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\n```\n\n\nextra search options\n--------------------\n\n__search all items__\n*as opposed to the regular search it is possible to find all matching subscriptions without using the path as the filter, but rather using the filter option, this will return all items that match the filter, regardless of their subscription path*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 4, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/blah/*/*', {ref: 5, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 6, topLevelRef:2});\ntameSearch.subscribe('test-subscriber', '/etc/*/*', {ref: 7, topLevelRef:2});\n\ntameSearch.searchAll({filter: {topLevelRef: 2}})\n//returns:\n// [\n//   {ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 3, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 6, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   {ref: 7, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n```\n\nextra unsubscribe options\n-------------------------\n\n__unsubscribe with returnRemoved:__\n*by default unsubscribe just returns the count of items removed from the subscriptions, add the returnRemoved:true option to return items removed from the subscription list*\n```javascript\n\nvar tameSearch = new TameSearch();\n\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 2});\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 3});\ntameSearch.search('/test/2', {filter: {ref: 3}});\n\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n\ntameSearch.unsubscribe('/test/*', {filter: {ref: 1}, returnRemoved:true});\n// returns:\n// [{ ref: 1, subscriberKey: 'test-subscriber' }]\n//instead of 1\n```\n\n__variable depth trailing wildcards:__\n*if a trailing wildcard is a double (glob style) the subscription will be for made for further levels of the topic up to a specific depth*\n```javascript\n\nvar tameSearch = TameSearch.create({defaultVariableDepth:5});//defaultVariableDepth default is 5\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'}, {depth:6}); \n//NB: will only work for a trailing wildcard (last 2 characters\n// in the topic) - ie: /this/is/a/**/bad/path \n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*/*', {test:'data'});\n\n//and\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data'});\n\n//is the same as:\n\ntameSearch.subscribe('test-subscriber', '/test/1/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*', {test:'data'});\ntameSearch.subscribe('test-subscriber', '/test/1/*/*/*/*/*', {test:'data'});\n\n// you unsubscribe using almost the same syntax\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {depth:6});\n\n//is the same as:\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*');\ntameSearch.unsubscribe('test-subscriber', '/test/1/*/*/*/*/*/*');\n\n// you can use a filter in the unsubscribe to ensure only a specific of items is unsubscribed\n\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:1});\ntameSearch.subscribe('test-subscriber', '/test/1/**', {test:'data', key:2});\n\ntameSearch.unsubscribe('test-subscriber', '/test/1/**', {filter:{key:1}});\n//will only subscribe all variable depth items with a key:1\n\n```\n\n__unsubscribe from all paths:__\n*you can unsubscribe from all paths, using a filter*\n```javascript\nvar tameSearch = new TameSearch();\ntameSearch.subscribe('test-subscriber', '/test/*', {ref: 1, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/*/*/*', {ref: 3, topLevelRef:2});\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:1}, returnRemoved:true})\n// returns:\n// [{ ref: 1, topLevelRef:1, subscriberKey: 'test-subscriber' }, { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' }]\n```\n\nrules / caveats\n---------------\n\nNB: a leading / is ignored when subscribing, unsubscribing and searching:\n\n```javascript\n\n    tameSearch.subscribe('test-subscriber', 'test/1/*/3', {ref:1});\n    tameSearch.subscribe('test-subscriber', '/test/1/*/3', {ref:2});\n\n    tameSearch.search('/test/1/*/3')\n    //returns:\n    // [\n    //   { ref:1, subscriberKey: 'test-subscriber' },\n    //   { ref:2, subscriberKey: 'test-subscriber' }\n    // ]\n```\n\ndifference between unsubscribeAny and unsubscribeAll\n*This could be confusing: unsubscribeAny removes specifically \"any\" subscriptions and ignores topic based ones, unsubscribeAll will remove topic and \"any\" type subscriptions*\n\n```javascript\n\nvar tameSearch = new TameSearch();\ntameSearch.subscribeAny('test-subscriber', {ref: 1, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 5, topLevelRef:2});\ntameSearch.subscribeAny('test-subscriber', {ref: 2, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/1', {ref: 3, topLevelRef:1});\ntameSearch.subscribe('test-subscriber', '/test/2', {ref: 4, topLevelRef:2});\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' },\n//   { ref: 2, topLevelRef:1, subscriberKey: 'test-subscriber' } \n// ]\n// NB: note how the last item in the results is always included with the search results as it is subscribed to any search event\n\ntameSearch.unsubscribeAny('test-subscriber', {filter:{topLevelRef:1}});\n\ntameSearch.search('/test/1', {filter: {topLevelRef: 1}});\n//now returns:\n// [\n//   { ref: 3, topLevelRef:1, subscriberKey: 'test-subscriber' }\n// ]\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//returns:\n// [\n//   { ref: 1, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 5, topLevelRef:2, subscriberKey: 'test-subscriber' },\n//   { ref: 4, topLevelRef:2, subscriberKey: 'test-subscriber' }\n// ]\n\n//NB: notice that the unsubscribeAll method removes both \"any\" and topic type subscriptions\ntameSearch.unsubscribeAll('test-subscriber', {filter:{topLevelRef:2}});\n\ntameSearch.search('/test/2', {filter: {topLevelRef: 2}});\n//now returns:\n// []  \n\n```\n\ncomparison is done only on paths that have a matching number of / segment dividers, ie:\n\n```javascript\n\n    tameSearch.search('/test/1'); //will not return subscriptions like /test/*/*, only test/1 or test/*\n\n```\n\nwildcards mean nothing in the search string (for now)\n\n```\n    tameSearch.search('/test/*'); //will not return the subscription \"/test/1\" or \"/test/2\", only \"/test/*\" because the paths match\n```\n\nsubscriberKey argument is required for subscribe and unsubscribe methods, and subscription reference data must be an object\n\n```javascript\n  tameSearch.subscribe(undefined, '/test/1/*/*', { test : 'data' }) //will not work, no subscriberKey\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*') //will not work\n  tameSearch.subscribe('test-subscriber', '/test/1/*/*','string value') //will not work\n  //instead do\n  tameSearch.subscribe('/test/1/*/*',{ value:'string value' })\n\n```\n","gitHead":"66a5e844f5b3c8b43653a268348a03d2ba1a9e8c","bugs":{"url":"https://github.com/happner/tame-search/issues"},"homepage":"https://github.com/happner/tame-search#readme","_id":"tame-search@3.0.11-prerelease-3","_nodeVersion":"16.13.1","_npmVersion":"8.5.4","dist":{"integrity":"sha512-7HbjAW4MMHoqiVswe34M/c61A1WL27FZQ+3lruU5KoOCjMgi3BVKGOz3KO6tVQEwn6ZN9dDZBBQRboC9XvXsOQ==","shasum":"8176a0d9d030760b1239ed03be32a32423767f1d","tarball":"https://registry.npmjs.org/tame-search/-/tame-search-3.0.11-prerelease-3.tgz","fileCount":4,"unpackedSize":25731,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDtv5wQIUC8UF7eBtINZam7vQsdQIdk+BL/TKZlOhmiqAiEAkQRCQ7I+4KUSrjhz9N5B1C14aMxcVW0pA+5mMfozty4="}]},"_npmUser":{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"},"directories":{},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"erasmusjw","email":"Erasmusjw@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tame-search_3.0.11-prerelease-3_1703153593056_0.866210562963778"},"_hasShrinkwrap":false}},"time":{"created":"2018-04-21T08:16:39.218Z","0.0.1":"2018-04-21T08:16:39.302Z","modified":"2023-12-21T10:13:13.409Z","1.0.0":"2018-04-22T09:14:44.543Z","1.0.1":"2018-05-10T09:28:42.412Z","1.0.2":"2018-05-10T09:35:52.213Z","1.1.0":"2018-09-06T09:27:43.413Z","1.1.1":"2018-09-06T11:46:24.536Z","1.2.0":"2018-09-06T14:01:16.741Z","1.2.2":"2018-09-13T07:06:43.914Z","1.3.0":"2018-09-26T10:18:32.290Z","1.4.0":"2018-11-13T15:07:40.031Z","1.4.1":"2018-11-13T17:00:58.180Z","2.0.0":"2020-07-15T08:25:37.382Z","3.0.0":"2022-03-01T20:08:20.041Z","3.0.1":"2022-03-03T13:12:26.641Z","3.0.2":"2022-03-11T11:34:17.483Z","3.0.3":"2022-03-30T06:51:35.761Z","3.0.4-prerelease.1":"2022-05-17T15:00:50.146Z","3.0.4":"2022-05-27T16:03:51.694Z","3.0.5-prerelease-1":"2022-07-14T11:54:25.187Z","3.0.5-prerelease-2":"2022-07-14T13:47:16.252Z","3.0.5":"2022-07-21T08:03:40.781Z","3.0.6":"2022-11-01T13:57:53.462Z","3.0.7":"2022-11-26T11:01:38.565Z","3.0.8-prerelease-1":"2023-01-11T17:13:48.653Z","3.0.8":"2023-01-18T10:58:19.156Z","3.0.9-prerelease-1":"2023-01-18T13:56:08.195Z","3.0.9-prerelease-2":"2023-01-26T10:38:52.955Z","3.0.9":"2023-02-06T11:51:07.416Z","3.0.10":"2023-08-06T11:50:17.170Z","3.0.11-prerelease-1":"2023-09-14T10:12:28.083Z","3.0.11-prerelease-2":"2023-10-06T07:43:21.119Z","3.0.11-prerelease-3":"2023-12-21T10:13:13.250Z"},"maintainers":[{"name":"smc-tenacious","email":"eggers.jens@gmail.com"},{"name":"erasmusjw","email":"Erasmusjw@gmail.com"},{"name":"simonbishopza","email":"simon.bishop.za@gmail.com"}],"description":"strict wildcard indexing and searching","homepage":"https://github.com/happner/tame-search#readme","keywords":["wildcard","search"],"repository":{"type":"git","url":"git+https://github.com/happner/tame-search.git"},"author":{"name":"Tenacious and NSOFT"},"bugs":{"url":"https://github.com/happner/tame-search/issues"},"license":"MIT","readme":"","readmeFilename":""}