@teambit/objects 0.0.735 → 0.0.737

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -102,7 +102,7 @@ describe('ModelComponent', () => {
102
102
  const ref = _objects().Ref.from(tagHash);
103
103
  component.setVersion('0.0.2', _objects().Ref.from('b'.repeat(40)));
104
104
  (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.equal('0.0.1');
105
- delete component.versions['0.0.1'];
105
+ component.removeVersion('0.0.1');
106
106
  (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.be.undefined;
107
107
  component.setVersion('0.0.5', ref);
108
108
  (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.equal('0.0.5');
@@ -115,6 +115,48 @@ describe('ModelComponent', () => {
115
115
  component.setVersion('0.0.8', ref);
116
116
  (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.equal('0.0.8');
117
117
  });
118
+ it('should find a tag added after a lookup, also after it was moved to the orphaned versions', () => {
119
+ const component = getModelComponent(getModelComponentFixture());
120
+ const ref = _objects().Ref.from('d'.repeat(40));
121
+ (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.be.undefined;
122
+ component.setVersion('0.0.9', ref);
123
+ (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.equal('0.0.9');
124
+ component.moveVersionToOrphaned('0.0.9');
125
+ (0, _chai().expect)(component.versions['0.0.9']).to.be.undefined;
126
+ (0, _chai().expect)(component.orphanedVersions['0.0.9']?.toString()).to.equal(ref.toString());
127
+ (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.equal('0.0.9');
128
+ });
129
+ it('should not find an orphaned tag after the orphaned versions were cleared', () => {
130
+ const component = getModelComponent(getModelComponentFixture());
131
+ const ref = _objects().Ref.from('e'.repeat(40));
132
+ component.setOrphanedVersion('0.0.4', ref);
133
+ (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.equal('0.0.4');
134
+ component.clearOrphanedVersions();
135
+ (0, _chai().expect)(component.getTagOfRefIfExists(ref)).to.be.undefined;
136
+ });
137
+ it('should serialize the versions as before and not the tags index, as `bit cat-scope --json` does', () => {
138
+ const component = getModelComponent(getModelComponentFixture());
139
+ component.setOrphanedVersion('0.0.3', _objects().Ref.from(orphanedHash));
140
+ component.getTagOfRefIfExists(_objects().Ref.from(tagHash));
141
+ const serialized = JSON.parse(JSON.stringify(component));
142
+ (0, _chai().expect)(serialized.versions).to.have.property('0.0.1');
143
+ (0, _chai().expect)(serialized.orphanedVersions).to.have.property('0.0.3');
144
+ (0, _chai().expect)(Object.keys(serialized).filter(key => /tag/i.test(key))).to.deep.equal([]);
145
+ });
146
+ it('should stay fast looking up every version of a component with many tags, and snaps that are not tags', () => {
147
+ const size = 20000;
148
+ const hash = i => i.toString(16).padStart(40, '0');
149
+ const component = getModelComponent(getModelComponentFixture());
150
+ for (let i = 0; i < size; i += 1) component.setVersion(`1.0.${i}`, _objects().Ref.from(hash(i)));
151
+ const refs = Array.from({
152
+ length: size * 2
153
+ }, (_, i) => _objects().Ref.from(hash(i)));
154
+ const start = Date.now();
155
+ const tags = component.switchHashesWithTagsIfExist(refs);
156
+ (0, _chai().expect)(tags[size - 1]).to.equal(`1.0.${size - 1}`);
157
+ (0, _chai().expect)(tags[size]).to.equal(hash(size));
158
+ (0, _chai().expect)(Date.now() - start).to.be.lessThan(2000);
159
+ });
118
160
  });
119
161
  describe('populateVersionHistoryIfMissingGracefully', () => {
120
162
  const hash = i => i.toString(16).padStart(40, '0');
@@ -1 +1 @@
1
- {"version":3,"names":["_chai","data","require","_modelComponent","_interopRequireDefault","_lodash","_objects","_versionHistory","e","__esModule","default","modelComponentFixture","name","scope","versions","lang","deprecated","bindingPrefix","remotes","url","date","state","local","getModelComponentFixture","cloneDeep","getModelComponent","obj","ModelComponent","parse","JSON","stringify","describe","validateFunc","modelComponent","before","fixture","validate","it","expect","to","throw","tagHash","orphanedHash","setOrphanedVersion","Ref","from","getRef","toString","equal","getTagOfRefIfExists","switchHashesWithTagsIfExist","repeat","deep","component","ref","setVersion","be","undefined","hash","i","padStart","versionObject","parents","map","fakeRepo","byHash","Map","v","loaded","load","r","push","get","writeObjectsToTheFS","historyHashes","versionHistory","getAllHashesAsString","sort","VersionHistory","create","repo","err","populateVersionHistoryIfMissingGracefully","filter","h","have","length","addFromVersionsObjects","added","instanceOf","Error","size","Array","_","start","Date","now","lessThan"],"sources":["model-component.spec.ts"],"sourcesContent":["import { expect } from 'chai';\n\nimport ModelComponent from './model-component';\nimport { cloneDeep } from 'lodash';\nimport { Ref } from '../objects';\nimport VersionHistory from './version-history';\n\nconst modelComponentFixture = {\n name: 'bar/foo',\n scope: 'remote-scope',\n versions: {\n '0.0.1': '125a37bdb17220bdc1406a9a28a3dde4eec91225',\n },\n lang: 'javascript',\n deprecated: false,\n bindingPrefix: '@bit',\n remotes: [\n {\n url: 'file:///tmp/remote-scope',\n name: 'remote-scope',\n date: '1572532837438',\n },\n ],\n state: {\n versions: {\n '0.0.1': {\n local: true,\n },\n },\n },\n};\n\nconst getModelComponentFixture = (): typeof modelComponentFixture => {\n return cloneDeep(modelComponentFixture);\n};\n\nconst getModelComponent = (obj: object): ModelComponent => {\n return ModelComponent.parse(JSON.stringify(obj));\n};\n\ndescribe('ModelComponent', () => {\n describe('validate', () => {\n let validateFunc: Function;\n describe('duplicate hashes', () => {\n let modelComponent: ModelComponent;\n before(() => {\n const fixture = getModelComponentFixture();\n fixture.versions['0.0.2'] = fixture.versions['0.0.1'];\n modelComponent = getModelComponent(fixture);\n validateFunc = () => modelComponent.validate();\n });\n it('should throw an error', () => {\n expect(validateFunc).to.throw('the following hash(es) are duplicated');\n });\n });\n });\n describe('versions lookup', () => {\n const tagHash = '125a37bdb17220bdc1406a9a28a3dde4eec91225';\n const orphanedHash = '225a37bdb17220bdc1406a9a28a3dde4eec91225';\n let modelComponent: ModelComponent;\n before(() => {\n modelComponent = getModelComponent(getModelComponentFixture());\n modelComponent.setOrphanedVersion('0.0.3', Ref.from(orphanedHash));\n });\n it('should find the ref of a tag and of an orphaned tag', () => {\n expect(modelComponent.getRef('0.0.1')?.toString()).to.equal(tagHash);\n expect(modelComponent.getRef('0.0.3')?.toString()).to.equal(orphanedHash);\n });\n it('should find the tag of a ref and of an orphaned ref', () => {\n expect(modelComponent.getTagOfRefIfExists(Ref.from(tagHash))).to.equal('0.0.1');\n expect(modelComponent.getTagOfRefIfExists(Ref.from(orphanedHash))).to.equal('0.0.3');\n expect(\n modelComponent.switchHashesWithTagsIfExist([Ref.from(orphanedHash), Ref.from('a'.repeat(40))])\n ).to.deep.equal(['0.0.3', 'a'.repeat(40)]);\n });\n it('should find the newest tag of a ref and not return a remembered tag after the versions changed', () => {\n const component = getModelComponent(getModelComponentFixture());\n const ref = Ref.from(tagHash);\n component.setVersion('0.0.2', Ref.from('b'.repeat(40)));\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.1');\n delete component.versions['0.0.1'];\n expect(component.getTagOfRefIfExists(ref)).to.be.undefined;\n component.setVersion('0.0.5', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.5');\n });\n it('should prefer a tag over an orphaned tag of the same ref, even after the orphaned one was found', () => {\n const component = getModelComponent(getModelComponentFixture());\n const ref = Ref.from('c'.repeat(40));\n component.setOrphanedVersion('0.0.7', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.7');\n component.setVersion('0.0.8', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.8');\n });\n });\n\n describe('populateVersionHistoryIfMissingGracefully', () => {\n const hash = (i: number) => i.toString(16).padStart(40, '0');\n const ref = (i: number) => new Ref(hash(i));\n /** a version object of the given number, as the history population reads it. */\n const versionObject = (i: number, parents: number[] = i > 0 ? [i - 1] : []): any => ({\n hash: () => ref(i),\n parents: parents.map(ref),\n });\n /** a repo holding these version objects, which records what it loads. */\n const fakeRepo = (versions: any[]) => {\n const byHash = new Map(versions.map((v) => [v.hash().toString(), v]));\n const loaded: string[] = [];\n return {\n loaded,\n load: async (r: Ref) => {\n loaded.push(r.toString());\n return byHash.get(r.toString());\n },\n writeObjectsToTheFS: async () => {},\n } as any;\n };\n const component = () => getModelComponent(getModelComponentFixture());\n const historyHashes = (versionHistory: VersionHistory) => versionHistory.getAllHashesAsString().sort();\n\n it('adds the head and all its ancestors to an empty history', async () => {\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo([0, 1, 2, 3].map((i) => versionObject(i)));\n const { err } = await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(err).to.be.undefined;\n expect(historyHashes(versionHistory)).to.deep.equal([0, 1, 2, 3].map(hash).sort());\n });\n\n it('loads a shared ancestor of a merge snap only once', async () => {\n // 0 <- 1 <- 3, 0 <- 2 <- 3\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo([versionObject(0), versionObject(1, [0]), versionObject(2, [0]), versionObject(3, [1, 2])]);\n await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(repo.loaded.filter((h: string) => h === hash(0))).to.have.length(1);\n expect(historyHashes(versionHistory)).to.deep.equal([0, 1, 2, 3].map(hash).sort());\n });\n\n it('stops at versions the history already has', async () => {\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n versionHistory.addFromVersionsObjects([versionObject(0), versionObject(1)]);\n const repo = fakeRepo([0, 1, 2, 3].map((i) => versionObject(i)));\n await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(repo.loaded).to.deep.equal([hash(3), hash(2)]);\n });\n\n it('returns the added versions and an error when a parent is missing', async () => {\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo([versionObject(2), versionObject(3)]);\n const { err, added } = await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(err).to.be.instanceOf(Error);\n expect(added?.map((v) => v.hash.toString())).to.deep.equal([hash(3), hash(2)]);\n });\n\n it('stays fast when the whole of a long history is missing', async () => {\n const size = 10000;\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo(Array.from({ length: size }, (_, i) => versionObject(i)));\n const start = Date.now();\n await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(size - 1));\n expect(versionHistory.versions).to.have.length(size);\n expect(Date.now() - start).to.be.lessThan(2000);\n });\n });\n});\n"],"mappings":";;AAAA,SAAAA,MAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,KAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,gBAAA;EAAA,MAAAF,IAAA,GAAAG,sBAAA,CAAAF,OAAA;EAAAC,eAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,QAAA;EAAA,MAAAJ,IAAA,GAAAC,OAAA;EAAAG,OAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,SAAA;EAAA,MAAAL,IAAA,GAAAC,OAAA;EAAAI,QAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAM,gBAAA;EAAA,MAAAN,IAAA,GAAAG,sBAAA,CAAAF,OAAA;EAAAK,eAAA,YAAAA,CAAA;IAAA,OAAAN,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA+C,SAAAG,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE/C,MAAMG,qBAAqB,GAAG;EAC5BC,IAAI,EAAE,SAAS;EACfC,KAAK,EAAE,cAAc;EACrBC,QAAQ,EAAE;IACR,OAAO,EAAE;EACX,CAAC;EACDC,IAAI,EAAE,YAAY;EAClBC,UAAU,EAAE,KAAK;EACjBC,aAAa,EAAE,MAAM;EACrBC,OAAO,EAAE,CACP;IACEC,GAAG,EAAE,0BAA0B;IAC/BP,IAAI,EAAE,cAAc;IACpBQ,IAAI,EAAE;EACR,CAAC,CACF;EACDC,KAAK,EAAE;IACLP,QAAQ,EAAE;MACR,OAAO,EAAE;QACPQ,KAAK,EAAE;MACT;IACF;EACF;AACF,CAAC;AAED,MAAMC,wBAAwB,GAAGA,CAAA,KAAoC;EACnE,OAAO,IAAAC,mBAAS,EAACb,qBAAqB,CAAC;AACzC,CAAC;AAED,MAAMc,iBAAiB,GAAIC,GAAW,IAAqB;EACzD,OAAOC,yBAAc,CAACC,KAAK,CAACC,IAAI,CAACC,SAAS,CAACJ,GAAG,CAAC,CAAC;AAClD,CAAC;AAEDK,QAAQ,CAAC,gBAAgB,EAAE,MAAM;EAC/BA,QAAQ,CAAC,UAAU,EAAE,MAAM;IACzB,IAAIC,YAAsB;IAC1BD,QAAQ,CAAC,kBAAkB,EAAE,MAAM;MACjC,IAAIE,cAA8B;MAClCC,MAAM,CAAC,MAAM;QACX,MAAMC,OAAO,GAAGZ,wBAAwB,CAAC,CAAC;QAC1CY,OAAO,CAACrB,QAAQ,CAAC,OAAO,CAAC,GAAGqB,OAAO,CAACrB,QAAQ,CAAC,OAAO,CAAC;QACrDmB,cAAc,GAAGR,iBAAiB,CAACU,OAAO,CAAC;QAC3CH,YAAY,GAAGA,CAAA,KAAMC,cAAc,CAACG,QAAQ,CAAC,CAAC;MAChD,CAAC,CAAC;MACFC,EAAE,CAAC,uBAAuB,EAAE,MAAM;QAChC,IAAAC,cAAM,EAACN,YAAY,CAAC,CAACO,EAAE,CAACC,KAAK,CAAC,uCAAuC,CAAC;MACxE,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ,CAAC,CAAC;EACFT,QAAQ,CAAC,iBAAiB,EAAE,MAAM;IAChC,MAAMU,OAAO,GAAG,0CAA0C;IAC1D,MAAMC,YAAY,GAAG,0CAA0C;IAC/D,IAAIT,cAA8B;IAClCC,MAAM,CAAC,MAAM;MACXD,cAAc,GAAGR,iBAAiB,CAACF,wBAAwB,CAAC,CAAC,CAAC;MAC9DU,cAAc,CAACU,kBAAkB,CAAC,OAAO,EAAEC,cAAG,CAACC,IAAI,CAACH,YAAY,CAAC,CAAC;IACpE,CAAC,CAAC;IACFL,EAAE,CAAC,qDAAqD,EAAE,MAAM;MAC9D,IAAAC,cAAM,EAACL,cAAc,CAACa,MAAM,CAAC,OAAO,CAAC,EAAEC,QAAQ,CAAC,CAAC,CAAC,CAACR,EAAE,CAACS,KAAK,CAACP,OAAO,CAAC;MACpE,IAAAH,cAAM,EAACL,cAAc,CAACa,MAAM,CAAC,OAAO,CAAC,EAAEC,QAAQ,CAAC,CAAC,CAAC,CAACR,EAAE,CAACS,KAAK,CAACN,YAAY,CAAC;IAC3E,CAAC,CAAC;IACFL,EAAE,CAAC,qDAAqD,EAAE,MAAM;MAC9D,IAAAC,cAAM,EAACL,cAAc,CAACgB,mBAAmB,CAACL,cAAG,CAACC,IAAI,CAACJ,OAAO,CAAC,CAAC,CAAC,CAACF,EAAE,CAACS,KAAK,CAAC,OAAO,CAAC;MAC/E,IAAAV,cAAM,EAACL,cAAc,CAACgB,mBAAmB,CAACL,cAAG,CAACC,IAAI,CAACH,YAAY,CAAC,CAAC,CAAC,CAACH,EAAE,CAACS,KAAK,CAAC,OAAO,CAAC;MACpF,IAAAV,cAAM,EACJL,cAAc,CAACiB,2BAA2B,CAAC,CAACN,cAAG,CAACC,IAAI,CAACH,YAAY,CAAC,EAAEE,cAAG,CAACC,IAAI,CAAC,GAAG,CAACM,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAC/F,CAAC,CAACZ,EAAE,CAACa,IAAI,CAACJ,KAAK,CAAC,CAAC,OAAO,EAAE,GAAG,CAACG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC;IACFd,EAAE,CAAC,gGAAgG,EAAE,MAAM;MACzG,MAAMgB,SAAS,GAAG5B,iBAAiB,CAACF,wBAAwB,CAAC,CAAC,CAAC;MAC/D,MAAM+B,GAAG,GAAGV,cAAG,CAACC,IAAI,CAACJ,OAAO,CAAC;MAC7BY,SAAS,CAACE,UAAU,CAAC,OAAO,EAAEX,cAAG,CAACC,IAAI,CAAC,GAAG,CAACM,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;MACvD,IAAAb,cAAM,EAACe,SAAS,CAACJ,mBAAmB,CAACK,GAAG,CAAC,CAAC,CAACf,EAAE,CAACS,KAAK,CAAC,OAAO,CAAC;MAC5D,OAAOK,SAAS,CAACvC,QAAQ,CAAC,OAAO,CAAC;MAClC,IAAAwB,cAAM,EAACe,SAAS,CAACJ,mBAAmB,CAACK,GAAG,CAAC,CAAC,CAACf,EAAE,CAACiB,EAAE,CAACC,SAAS;MAC1DJ,SAAS,CAACE,UAAU,CAAC,OAAO,EAAED,GAAG,CAAC;MAClC,IAAAhB,cAAM,EAACe,SAAS,CAACJ,mBAAmB,CAACK,GAAG,CAAC,CAAC,CAACf,EAAE,CAACS,KAAK,CAAC,OAAO,CAAC;IAC9D,CAAC,CAAC;IACFX,EAAE,CAAC,iGAAiG,EAAE,MAAM;MAC1G,MAAMgB,SAAS,GAAG5B,iBAAiB,CAACF,wBAAwB,CAAC,CAAC,CAAC;MAC/D,MAAM+B,GAAG,GAAGV,cAAG,CAACC,IAAI,CAAC,GAAG,CAACM,MAAM,CAAC,EAAE,CAAC,CAAC;MACpCE,SAAS,CAACV,kBAAkB,CAAC,OAAO,EAAEW,GAAG,CAAC;MAC1C,IAAAhB,cAAM,EAACe,SAAS,CAACJ,mBAAmB,CAACK,GAAG,CAAC,CAAC,CAACf,EAAE,CAACS,KAAK,CAAC,OAAO,CAAC;MAC5DK,SAAS,CAACE,UAAU,CAAC,OAAO,EAAED,GAAG,CAAC;MAClC,IAAAhB,cAAM,EAACe,SAAS,CAACJ,mBAAmB,CAACK,GAAG,CAAC,CAAC,CAACf,EAAE,CAACS,KAAK,CAAC,OAAO,CAAC;IAC9D,CAAC,CAAC;EACJ,CAAC,CAAC;EAEFjB,QAAQ,CAAC,2CAA2C,EAAE,MAAM;IAC1D,MAAM2B,IAAI,GAAIC,CAAS,IAAKA,CAAC,CAACZ,QAAQ,CAAC,EAAE,CAAC,CAACa,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IAC5D,MAAMN,GAAG,GAAIK,CAAS,IAAK,KAAIf,cAAG,EAACc,IAAI,CAACC,CAAC,CAAC,CAAC;IAC3C;IACA,MAAME,aAAa,GAAGA,CAACF,CAAS,EAAEG,OAAiB,GAAGH,CAAC,GAAG,CAAC,GAAG,CAACA,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,MAAW;MACnFD,IAAI,EAAEA,CAAA,KAAMJ,GAAG,CAACK,CAAC,CAAC;MAClBG,OAAO,EAAEA,OAAO,CAACC,GAAG,CAACT,GAAG;IAC1B,CAAC,CAAC;IACF;IACA,MAAMU,QAAQ,GAAIlD,QAAe,IAAK;MACpC,MAAMmD,MAAM,GAAG,IAAIC,GAAG,CAACpD,QAAQ,CAACiD,GAAG,CAAEI,CAAC,IAAK,CAACA,CAAC,CAACT,IAAI,CAAC,CAAC,CAACX,QAAQ,CAAC,CAAC,EAAEoB,CAAC,CAAC,CAAC,CAAC;MACrE,MAAMC,MAAgB,GAAG,EAAE;MAC3B,OAAO;QACLA,MAAM;QACNC,IAAI,EAAE,MAAOC,CAAM,IAAK;UACtBF,MAAM,CAACG,IAAI,CAACD,CAAC,CAACvB,QAAQ,CAAC,CAAC,CAAC;UACzB,OAAOkB,MAAM,CAACO,GAAG,CAACF,CAAC,CAACvB,QAAQ,CAAC,CAAC,CAAC;QACjC,CAAC;QACD0B,mBAAmB,EAAE,MAAAA,CAAA,KAAY,CAAC;MACpC,CAAC;IACH,CAAC;IACD,MAAMpB,SAAS,GAAGA,CAAA,KAAM5B,iBAAiB,CAACF,wBAAwB,CAAC,CAAC,CAAC;IACrE,MAAMmD,aAAa,GAAIC,cAA8B,IAAKA,cAAc,CAACC,oBAAoB,CAAC,CAAC,CAACC,IAAI,CAAC,CAAC;IAEtGxC,EAAE,CAAC,yDAAyD,EAAE,YAAY;MACxE,MAAMsC,cAAc,GAAGG,yBAAc,CAACC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,CAAC;MAC3E,MAAMC,IAAI,GAAGhB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAACD,GAAG,CAAEJ,CAAC,IAAKE,aAAa,CAACF,CAAC,CAAC,CAAC,CAAC;MAChE,MAAM;QAAEsB;MAAI,CAAC,GAAG,MAAM5B,SAAS,CAAC,CAAC,CAAC6B,yCAAyC,CAACF,IAAI,EAAEL,cAAc,EAAErB,GAAG,CAAC,CAAC,CAAC,CAAC;MACzG,IAAAhB,cAAM,EAAC2C,GAAG,CAAC,CAAC1C,EAAE,CAACiB,EAAE,CAACC,SAAS;MAC3B,IAAAnB,cAAM,EAACoC,aAAa,CAACC,cAAc,CAAC,CAAC,CAACpC,EAAE,CAACa,IAAI,CAACJ,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAACe,GAAG,CAACL,IAAI,CAAC,CAACmB,IAAI,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC;IAEFxC,EAAE,CAAC,mDAAmD,EAAE,YAAY;MAClE;MACA,MAAMsC,cAAc,GAAGG,yBAAc,CAACC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,CAAC;MAC3E,MAAMC,IAAI,GAAGhB,QAAQ,CAAC,CAACH,aAAa,CAAC,CAAC,CAAC,EAAEA,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAEA,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAEA,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;MACjH,MAAMR,SAAS,CAAC,CAAC,CAAC6B,yCAAyC,CAACF,IAAI,EAAEL,cAAc,EAAErB,GAAG,CAAC,CAAC,CAAC,CAAC;MACzF,IAAAhB,cAAM,EAAC0C,IAAI,CAACZ,MAAM,CAACe,MAAM,CAAEC,CAAS,IAAKA,CAAC,KAAK1B,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAACnB,EAAE,CAAC8C,IAAI,CAACC,MAAM,CAAC,CAAC,CAAC;MAC1E,IAAAhD,cAAM,EAACoC,aAAa,CAACC,cAAc,CAAC,CAAC,CAACpC,EAAE,CAACa,IAAI,CAACJ,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAACe,GAAG,CAACL,IAAI,CAAC,CAACmB,IAAI,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC;IAEFxC,EAAE,CAAC,2CAA2C,EAAE,YAAY;MAC1D,MAAMsC,cAAc,GAAGG,yBAAc,CAACC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,CAAC;MAC3EJ,cAAc,CAACY,sBAAsB,CAAC,CAAC1B,aAAa,CAAC,CAAC,CAAC,EAAEA,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;MAC3E,MAAMmB,IAAI,GAAGhB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAACD,GAAG,CAAEJ,CAAC,IAAKE,aAAa,CAACF,CAAC,CAAC,CAAC,CAAC;MAChE,MAAMN,SAAS,CAAC,CAAC,CAAC6B,yCAAyC,CAACF,IAAI,EAAEL,cAAc,EAAErB,GAAG,CAAC,CAAC,CAAC,CAAC;MACzF,IAAAhB,cAAM,EAAC0C,IAAI,CAACZ,MAAM,CAAC,CAAC7B,EAAE,CAACa,IAAI,CAACJ,KAAK,CAAC,CAACU,IAAI,CAAC,CAAC,CAAC,EAAEA,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC;IAEFrB,EAAE,CAAC,kEAAkE,EAAE,YAAY;MACjF,MAAMsC,cAAc,GAAGG,yBAAc,CAACC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,CAAC;MAC3E,MAAMC,IAAI,GAAGhB,QAAQ,CAAC,CAACH,aAAa,CAAC,CAAC,CAAC,EAAEA,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;MAC3D,MAAM;QAAEoB,GAAG;QAAEO;MAAM,CAAC,GAAG,MAAMnC,SAAS,CAAC,CAAC,CAAC6B,yCAAyC,CAACF,IAAI,EAAEL,cAAc,EAAErB,GAAG,CAAC,CAAC,CAAC,CAAC;MAChH,IAAAhB,cAAM,EAAC2C,GAAG,CAAC,CAAC1C,EAAE,CAACiB,EAAE,CAACiC,UAAU,CAACC,KAAK,CAAC;MACnC,IAAApD,cAAM,EAACkD,KAAK,EAAEzB,GAAG,CAAEI,CAAC,IAAKA,CAAC,CAACT,IAAI,CAACX,QAAQ,CAAC,CAAC,CAAC,CAAC,CAACR,EAAE,CAACa,IAAI,CAACJ,KAAK,CAAC,CAACU,IAAI,CAAC,CAAC,CAAC,EAAEA,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC;IAEFrB,EAAE,CAAC,wDAAwD,EAAE,YAAY;MACvE,MAAMsD,IAAI,GAAG,KAAK;MAClB,MAAMhB,cAAc,GAAGG,yBAAc,CAACC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,CAAC;MAC3E,MAAMC,IAAI,GAAGhB,QAAQ,CAAC4B,KAAK,CAAC/C,IAAI,CAAC;QAAEyC,MAAM,EAAEK;MAAK,CAAC,EAAE,CAACE,CAAC,EAAElC,CAAC,KAAKE,aAAa,CAACF,CAAC,CAAC,CAAC,CAAC;MAC/E,MAAMmC,KAAK,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;MACxB,MAAM3C,SAAS,CAAC,CAAC,CAAC6B,yCAAyC,CAACF,IAAI,EAAEL,cAAc,EAAErB,GAAG,CAACqC,IAAI,GAAG,CAAC,CAAC,CAAC;MAChG,IAAArD,cAAM,EAACqC,cAAc,CAAC7D,QAAQ,CAAC,CAACyB,EAAE,CAAC8C,IAAI,CAACC,MAAM,CAACK,IAAI,CAAC;MACpD,IAAArD,cAAM,EAACyD,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGF,KAAK,CAAC,CAACvD,EAAE,CAACiB,EAAE,CAACyC,QAAQ,CAAC,IAAI,CAAC;IACjD,CAAC,CAAC;EACJ,CAAC,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_chai","data","require","_modelComponent","_interopRequireDefault","_lodash","_objects","_versionHistory","e","__esModule","default","modelComponentFixture","name","scope","versions","lang","deprecated","bindingPrefix","remotes","url","date","state","local","getModelComponentFixture","cloneDeep","getModelComponent","obj","ModelComponent","parse","JSON","stringify","describe","validateFunc","modelComponent","before","fixture","validate","it","expect","to","throw","tagHash","orphanedHash","setOrphanedVersion","Ref","from","getRef","toString","equal","getTagOfRefIfExists","switchHashesWithTagsIfExist","repeat","deep","component","ref","setVersion","removeVersion","be","undefined","moveVersionToOrphaned","orphanedVersions","clearOrphanedVersions","serialized","have","property","Object","keys","filter","key","test","size","hash","i","padStart","refs","Array","length","_","start","Date","now","tags","lessThan","versionObject","parents","map","fakeRepo","byHash","Map","v","loaded","load","r","push","get","writeObjectsToTheFS","historyHashes","versionHistory","getAllHashesAsString","sort","VersionHistory","create","repo","err","populateVersionHistoryIfMissingGracefully","h","addFromVersionsObjects","added","instanceOf","Error"],"sources":["model-component.spec.ts"],"sourcesContent":["import { expect } from 'chai';\n\nimport ModelComponent from './model-component';\nimport { cloneDeep } from 'lodash';\nimport { Ref } from '../objects';\nimport VersionHistory from './version-history';\n\nconst modelComponentFixture = {\n name: 'bar/foo',\n scope: 'remote-scope',\n versions: {\n '0.0.1': '125a37bdb17220bdc1406a9a28a3dde4eec91225',\n },\n lang: 'javascript',\n deprecated: false,\n bindingPrefix: '@bit',\n remotes: [\n {\n url: 'file:///tmp/remote-scope',\n name: 'remote-scope',\n date: '1572532837438',\n },\n ],\n state: {\n versions: {\n '0.0.1': {\n local: true,\n },\n },\n },\n};\n\nconst getModelComponentFixture = (): typeof modelComponentFixture => {\n return cloneDeep(modelComponentFixture);\n};\n\nconst getModelComponent = (obj: object): ModelComponent => {\n return ModelComponent.parse(JSON.stringify(obj));\n};\n\ndescribe('ModelComponent', () => {\n describe('validate', () => {\n let validateFunc: Function;\n describe('duplicate hashes', () => {\n let modelComponent: ModelComponent;\n before(() => {\n const fixture = getModelComponentFixture();\n fixture.versions['0.0.2'] = fixture.versions['0.0.1'];\n modelComponent = getModelComponent(fixture);\n validateFunc = () => modelComponent.validate();\n });\n it('should throw an error', () => {\n expect(validateFunc).to.throw('the following hash(es) are duplicated');\n });\n });\n });\n describe('versions lookup', () => {\n const tagHash = '125a37bdb17220bdc1406a9a28a3dde4eec91225';\n const orphanedHash = '225a37bdb17220bdc1406a9a28a3dde4eec91225';\n let modelComponent: ModelComponent;\n before(() => {\n modelComponent = getModelComponent(getModelComponentFixture());\n modelComponent.setOrphanedVersion('0.0.3', Ref.from(orphanedHash));\n });\n it('should find the ref of a tag and of an orphaned tag', () => {\n expect(modelComponent.getRef('0.0.1')?.toString()).to.equal(tagHash);\n expect(modelComponent.getRef('0.0.3')?.toString()).to.equal(orphanedHash);\n });\n it('should find the tag of a ref and of an orphaned ref', () => {\n expect(modelComponent.getTagOfRefIfExists(Ref.from(tagHash))).to.equal('0.0.1');\n expect(modelComponent.getTagOfRefIfExists(Ref.from(orphanedHash))).to.equal('0.0.3');\n expect(\n modelComponent.switchHashesWithTagsIfExist([Ref.from(orphanedHash), Ref.from('a'.repeat(40))])\n ).to.deep.equal(['0.0.3', 'a'.repeat(40)]);\n });\n it('should find the newest tag of a ref and not return a remembered tag after the versions changed', () => {\n const component = getModelComponent(getModelComponentFixture());\n const ref = Ref.from(tagHash);\n component.setVersion('0.0.2', Ref.from('b'.repeat(40)));\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.1');\n component.removeVersion('0.0.1');\n expect(component.getTagOfRefIfExists(ref)).to.be.undefined;\n component.setVersion('0.0.5', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.5');\n });\n it('should prefer a tag over an orphaned tag of the same ref, even after the orphaned one was found', () => {\n const component = getModelComponent(getModelComponentFixture());\n const ref = Ref.from('c'.repeat(40));\n component.setOrphanedVersion('0.0.7', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.7');\n component.setVersion('0.0.8', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.8');\n });\n it('should find a tag added after a lookup, also after it was moved to the orphaned versions', () => {\n const component = getModelComponent(getModelComponentFixture());\n const ref = Ref.from('d'.repeat(40));\n expect(component.getTagOfRefIfExists(ref)).to.be.undefined;\n component.setVersion('0.0.9', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.9');\n component.moveVersionToOrphaned('0.0.9');\n expect(component.versions['0.0.9']).to.be.undefined;\n expect(component.orphanedVersions['0.0.9']?.toString()).to.equal(ref.toString());\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.9');\n });\n it('should not find an orphaned tag after the orphaned versions were cleared', () => {\n const component = getModelComponent(getModelComponentFixture());\n const ref = Ref.from('e'.repeat(40));\n component.setOrphanedVersion('0.0.4', ref);\n expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.4');\n component.clearOrphanedVersions();\n expect(component.getTagOfRefIfExists(ref)).to.be.undefined;\n });\n it('should serialize the versions as before and not the tags index, as `bit cat-scope --json` does', () => {\n const component = getModelComponent(getModelComponentFixture());\n component.setOrphanedVersion('0.0.3', Ref.from(orphanedHash));\n component.getTagOfRefIfExists(Ref.from(tagHash));\n const serialized = JSON.parse(JSON.stringify(component));\n expect(serialized.versions).to.have.property('0.0.1');\n expect(serialized.orphanedVersions).to.have.property('0.0.3');\n expect(Object.keys(serialized).filter((key) => /tag/i.test(key))).to.deep.equal([]);\n });\n it('should stay fast looking up every version of a component with many tags, and snaps that are not tags', () => {\n const size = 20000;\n const hash = (i: number) => i.toString(16).padStart(40, '0');\n const component = getModelComponent(getModelComponentFixture());\n for (let i = 0; i < size; i += 1) component.setVersion(`1.0.${i}`, Ref.from(hash(i)));\n const refs = Array.from({ length: size * 2 }, (_, i) => Ref.from(hash(i)));\n const start = Date.now();\n const tags = component.switchHashesWithTagsIfExist(refs);\n expect(tags[size - 1]).to.equal(`1.0.${size - 1}`);\n expect(tags[size]).to.equal(hash(size));\n expect(Date.now() - start).to.be.lessThan(2000);\n });\n });\n\n describe('populateVersionHistoryIfMissingGracefully', () => {\n const hash = (i: number) => i.toString(16).padStart(40, '0');\n const ref = (i: number) => new Ref(hash(i));\n /** a version object of the given number, as the history population reads it. */\n const versionObject = (i: number, parents: number[] = i > 0 ? [i - 1] : []): any => ({\n hash: () => ref(i),\n parents: parents.map(ref),\n });\n /** a repo holding these version objects, which records what it loads. */\n const fakeRepo = (versions: any[]) => {\n const byHash = new Map(versions.map((v) => [v.hash().toString(), v]));\n const loaded: string[] = [];\n return {\n loaded,\n load: async (r: Ref) => {\n loaded.push(r.toString());\n return byHash.get(r.toString());\n },\n writeObjectsToTheFS: async () => {},\n } as any;\n };\n const component = () => getModelComponent(getModelComponentFixture());\n const historyHashes = (versionHistory: VersionHistory) => versionHistory.getAllHashesAsString().sort();\n\n it('adds the head and all its ancestors to an empty history', async () => {\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo([0, 1, 2, 3].map((i) => versionObject(i)));\n const { err } = await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(err).to.be.undefined;\n expect(historyHashes(versionHistory)).to.deep.equal([0, 1, 2, 3].map(hash).sort());\n });\n\n it('loads a shared ancestor of a merge snap only once', async () => {\n // 0 <- 1 <- 3, 0 <- 2 <- 3\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo([versionObject(0), versionObject(1, [0]), versionObject(2, [0]), versionObject(3, [1, 2])]);\n await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(repo.loaded.filter((h: string) => h === hash(0))).to.have.length(1);\n expect(historyHashes(versionHistory)).to.deep.equal([0, 1, 2, 3].map(hash).sort());\n });\n\n it('stops at versions the history already has', async () => {\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n versionHistory.addFromVersionsObjects([versionObject(0), versionObject(1)]);\n const repo = fakeRepo([0, 1, 2, 3].map((i) => versionObject(i)));\n await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(repo.loaded).to.deep.equal([hash(3), hash(2)]);\n });\n\n it('returns the added versions and an error when a parent is missing', async () => {\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo([versionObject(2), versionObject(3)]);\n const { err, added } = await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(3));\n expect(err).to.be.instanceOf(Error);\n expect(added?.map((v) => v.hash.toString())).to.deep.equal([hash(3), hash(2)]);\n });\n\n it('stays fast when the whole of a long history is missing', async () => {\n const size = 10000;\n const versionHistory = VersionHistory.create('bar/foo', 'remote-scope', []);\n const repo = fakeRepo(Array.from({ length: size }, (_, i) => versionObject(i)));\n const start = Date.now();\n await component().populateVersionHistoryIfMissingGracefully(repo, versionHistory, ref(size - 1));\n expect(versionHistory.versions).to.have.length(size);\n expect(Date.now() - start).to.be.lessThan(2000);\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -78,7 +78,7 @@ describe('ModelComponent', () => {
78
78
  const ref = Ref.from(tagHash);
79
79
  component.setVersion('0.0.2', Ref.from('b'.repeat(40)));
80
80
  expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.1');
81
- delete component.versions['0.0.1'];
81
+ component.removeVersion('0.0.1');
82
82
  expect(component.getTagOfRefIfExists(ref)).to.be.undefined;
83
83
  component.setVersion('0.0.5', ref);
84
84
  expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.5');
@@ -91,6 +91,46 @@ describe('ModelComponent', () => {
91
91
  component.setVersion('0.0.8', ref);
92
92
  expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.8');
93
93
  });
94
+ it('should find a tag added after a lookup, also after it was moved to the orphaned versions', () => {
95
+ const component = getModelComponent(getModelComponentFixture());
96
+ const ref = Ref.from('d'.repeat(40));
97
+ expect(component.getTagOfRefIfExists(ref)).to.be.undefined;
98
+ component.setVersion('0.0.9', ref);
99
+ expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.9');
100
+ component.moveVersionToOrphaned('0.0.9');
101
+ expect(component.versions['0.0.9']).to.be.undefined;
102
+ expect(component.orphanedVersions['0.0.9']?.toString()).to.equal(ref.toString());
103
+ expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.9');
104
+ });
105
+ it('should not find an orphaned tag after the orphaned versions were cleared', () => {
106
+ const component = getModelComponent(getModelComponentFixture());
107
+ const ref = Ref.from('e'.repeat(40));
108
+ component.setOrphanedVersion('0.0.4', ref);
109
+ expect(component.getTagOfRefIfExists(ref)).to.equal('0.0.4');
110
+ component.clearOrphanedVersions();
111
+ expect(component.getTagOfRefIfExists(ref)).to.be.undefined;
112
+ });
113
+ it('should serialize the versions as before and not the tags index, as `bit cat-scope --json` does', () => {
114
+ const component = getModelComponent(getModelComponentFixture());
115
+ component.setOrphanedVersion('0.0.3', Ref.from(orphanedHash));
116
+ component.getTagOfRefIfExists(Ref.from(tagHash));
117
+ const serialized = JSON.parse(JSON.stringify(component));
118
+ expect(serialized.versions).to.have.property('0.0.1');
119
+ expect(serialized.orphanedVersions).to.have.property('0.0.3');
120
+ expect(Object.keys(serialized).filter((key) => /tag/i.test(key))).to.deep.equal([]);
121
+ });
122
+ it('should stay fast looking up every version of a component with many tags, and snaps that are not tags', () => {
123
+ const size = 20000;
124
+ const hash = (i: number) => i.toString(16).padStart(40, '0');
125
+ const component = getModelComponent(getModelComponentFixture());
126
+ for (let i = 0; i < size; i += 1) component.setVersion(`1.0.${i}`, Ref.from(hash(i)));
127
+ const refs = Array.from({ length: size * 2 }, (_, i) => Ref.from(hash(i)));
128
+ const start = Date.now();
129
+ const tags = component.switchHashesWithTagsIfExist(refs);
130
+ expect(tags[size - 1]).to.equal(`1.0.${size - 1}`);
131
+ expect(tags[size]).to.equal(hash(size));
132
+ expect(Date.now() - start).to.be.lessThan(2000);
133
+ });
94
134
  });
95
135
 
96
136
  describe('populateVersionHistoryIfMissingGracefully', () => {
@@ -1,4 +1,4 @@
1
- import { forEach, isEmpty, pickBy, mapValues, isEqual, clone, findLastKey } from 'lodash';
1
+ import { forEach, isEmpty, pickBy, mapValues, isEqual, clone } from 'lodash';
2
2
  import { Mutex } from 'async-mutex';
3
3
  import * as semver from 'semver';
4
4
  import { versionParser, isHash, isTag, isSnap, LATEST_VERSION } from '@teambit/component-version';
@@ -95,6 +95,24 @@ export type ComponentProps = {
95
95
  detachedHeads?: DetachedHeads;
96
96
  };
97
97
 
98
+ /**
99
+ * the tag of each hash. a later tag of the same hash overrides an earlier one, so pass the maps by ascending
100
+ * precedence. within a map the newest tag wins, as tags keep insertion order.
101
+ */
102
+ function indexTagsByHash(...versionsMaps: Readonly<Versions>[]): Map<string, string> {
103
+ const tagsByHash = new Map<string, string>();
104
+ for (const versions of versionsMaps) {
105
+ for (const tag in versions) tagsByHash.set(versions[tag].toString(), tag);
106
+ }
107
+ return tagsByHash;
108
+ }
109
+
110
+ /**
111
+ * the index of `getTagOfRefIfExists` per component, built on demand. kept off the component itself, so it's not
112
+ * serialized with it (e.g. by `bit cat-scope --json`).
113
+ */
114
+ const tagsByHashIndex = new WeakMap<Component, Map<string, string>>();
115
+
98
116
  export const VERSION_ZERO = '0.0.0';
99
117
 
100
118
  /**
@@ -105,8 +123,11 @@ export const VERSION_ZERO = '0.0.0';
105
123
  export default class Component extends BitObject {
106
124
  scope: string;
107
125
  name: string;
108
- versions: Versions;
109
- orphanedVersions: Versions;
126
+ /**
127
+ * read-only from outside, so every write goes through a method of this class, which drops the tags index.
128
+ */
129
+ readonly versions: Readonly<Versions>;
130
+ readonly orphanedVersions: Readonly<Versions>;
110
131
  lang: string;
111
132
  /**
112
133
  * @deprecated moved to the Version object inside teambit/deprecation aspect
@@ -145,7 +166,6 @@ export default class Component extends BitObject {
145
166
  detachedHeads: DetachedHeads;
146
167
  private divergeData?: SnapsDistance;
147
168
  private _populateVersionHistoryMutex?: Mutex;
148
- private lastFoundTag?: string;
149
169
  constructor(props: ComponentProps) {
150
170
  super();
151
171
  if (!props.name) throw new TypeError('Model Component constructor expects to get a name parameter');
@@ -173,13 +193,22 @@ export default class Component extends BitObject {
173
193
  return this._populateVersionHistoryMutex;
174
194
  }
175
195
 
196
+ private get writableVersions(): Versions {
197
+ return this.versions as Versions;
198
+ }
199
+
200
+ private get writableOrphanedVersions(): Versions {
201
+ return this.orphanedVersions as Versions;
202
+ }
203
+
176
204
  get versionArray(): Ref[] {
177
205
  return Object.values(this.versions);
178
206
  }
179
207
 
180
208
  setVersion(tag: string, ref: Ref) {
181
- this.versions[tag] = ref;
182
- delete this.orphanedVersions[tag]; // just in case it's there.
209
+ this.writableVersions[tag] = ref;
210
+ delete this.writableOrphanedVersions[tag]; // just in case it's there.
211
+ tagsByHashIndex.delete(this);
183
212
  }
184
213
 
185
214
  setOrphanedVersion(tag: string, ref: Ref) {
@@ -188,7 +217,20 @@ export default class Component extends BitObject {
188
217
  `unable to save orphanedVersion "${tag}" for "${this.id()}" because this tag is already part of the versions prop`
189
218
  );
190
219
  }
191
- this.orphanedVersions[tag] = ref;
220
+ this.writableOrphanedVersions[tag] = ref;
221
+ tagsByHashIndex.delete(this);
222
+ }
223
+
224
+ clearOrphanedVersions() {
225
+ Object.keys(this.orphanedVersions).forEach((tag) => delete this.writableOrphanedVersions[tag]);
226
+ tagsByHashIndex.delete(this);
227
+ }
228
+
229
+ moveVersionToOrphaned(tag: string) {
230
+ const ref = this.versions[tag];
231
+ if (!ref) throw new Error(`moveVersionToOrphaned failed finding version ${tag} of ${this.id()}`);
232
+ delete this.writableVersions[tag];
233
+ this.setOrphanedVersion(tag, ref);
192
234
  }
193
235
 
194
236
  getRef(version: string): Ref | null {
@@ -652,18 +694,14 @@ export default class Component extends BitObject {
652
694
  }
653
695
 
654
696
  getTagOfRefIfExists(ref: Ref): string | undefined {
655
- // the same ref (usually the head) is looked up many times per command, and each scan has to list all the tags.
656
- // the last hit is re-checked against the current versions, so it can't go stale when versions change. only hits
657
- // in `versions` are remembered, so they keep their precedence over orphaned versions.
658
- if (this.lastFoundTag && this.versions[this.lastFoundTag]?.isEqual(ref)) return this.lastFoundTag;
659
- // search from the newest tag. tags are kept in insertion order and the head is usually the latest one.
660
- const findIn = (versions: Versions) => findLastKey(versions, (versionRef) => versionRef.isEqual(ref));
661
- const tag = findIn(this.versions);
662
- if (tag) {
663
- this.lastFoundTag = tag;
664
- return tag;
697
+ // called for every version of a history walk, so it's a lookup in an index rather than a scan of all the tags.
698
+ // a tag in `versions` takes precedence over an orphaned one.
699
+ let tagsByHash = tagsByHashIndex.get(this);
700
+ if (!tagsByHash) {
701
+ tagsByHash = indexTagsByHash(this.orphanedVersions, this.versions);
702
+ tagsByHashIndex.set(this, tagsByHash);
665
703
  }
666
- return findIn(this.orphanedVersions);
704
+ return tagsByHash.get(ref.toString());
667
705
  }
668
706
 
669
707
  getTag(version: string): string | undefined {
@@ -1019,7 +1057,8 @@ consider using --ignore-missing-artifacts flag if you're sure the artifacts are
1019
1057
  removeVersion(version: string): Ref {
1020
1058
  const objectRef = this.getRef(version);
1021
1059
  if (!objectRef) throw new Error(`removeVersion failed finding version ${version}`);
1022
- delete this.versions[version];
1060
+ delete this.writableVersions[version];
1061
+ tagsByHashIndex.delete(this);
1023
1062
  if (this.state.versions && this.state.versions[version]) delete this.state.versions[version];
1024
1063
  return objectRef;
1025
1064
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@teambit/objects",
3
- "version": "0.0.735",
3
+ "version": "0.0.737",
4
4
  "homepage": "https://bit.cloud/teambit/scope/objects",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.scope",
8
8
  "name": "objects",
9
- "version": "0.0.735"
9
+ "version": "0.0.737"
10
10
  },
11
11
  "dependencies": {
12
12
  "@pnpm/lockfile.types": "1100.0.19",
@@ -22,16 +22,13 @@
22
22
  "@teambit/harmony.modules.runtimes": "0.0.4",
23
23
  "@teambit/component-id": "1.2.5",
24
24
  "@teambit/legacy.utils": "0.0.57",
25
- "@teambit/harmony.modules.get-basic-log": "0.0.199",
26
25
  "@teambit/bit-error": "0.0.404",
27
26
  "@teambit/component-version": "1.0.4",
28
27
  "@teambit/component.snap-distance": "0.0.194",
29
- "@teambit/config-store": "0.0.310",
30
28
  "@teambit/lane-id": "0.0.312",
31
29
  "@teambit/legacy.cli.error": "0.0.72",
32
30
  "@teambit/legacy.constants": "0.0.50",
33
31
  "@teambit/legacy.logger": "0.0.71",
34
- "@teambit/legacy.scope": "0.0.198",
35
32
  "@teambit/toolbox.crypto.sha1": "0.0.24",
36
33
  "@teambit/component.sources": "0.0.246",
37
34
  "@teambit/harmony.modules.concurrency": "0.0.51",
@@ -47,7 +44,10 @@
47
44
  "@teambit/bit.get-bit-version": "0.0.31",
48
45
  "@teambit/semantics.doc-parser": "0.0.202",
49
46
  "@teambit/harmony.modules.in-memory-cache": "0.0.55",
50
- "@teambit/toolbox.fs.remove-empty-dir": "0.0.22"
47
+ "@teambit/toolbox.fs.remove-empty-dir": "0.0.22",
48
+ "@teambit/harmony.modules.get-basic-log": "0.0.201",
49
+ "@teambit/config-store": "0.0.312",
50
+ "@teambit/legacy.scope": "0.0.200"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/semver": "7.5.8",